I opened a git repo by VS Code, but it shows No source control providers registered. One possible reason is that VS Code couldn’t find the executable git command, so we can set the executable path of git in settings. Open File -> Preferences -> Settings, then find the Git: Path setting, click Edit in settings.json, and add "git.path": "full-path-to-git" to settings.json.

Reference:

Integer 类的内部维护了一个 IntegerCache 的静态类,默认缓存了-128到127的 Integer 对象,而 java.lang.Integer#valueOf(int) 方法执行时会判断参数是否在-128到127之间,如果在这个区间,则返回 IntegerCache 内部的缓存对象,所以 Integer.valueOf(127) == Integer.valueOf(127)True

不过,整型缓存只适用于自动装箱的情况,不适用于通过构造函数创建的 Integer 对象间的比较,在下述代码中,最终的输出结果是 integer1 == integer2integer3 != integer4

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Integer integer1 = 3;
Integer integer2 = 3;

if (integer1 == integer2) {
System.out.println("integer1 == integer2");
} else {
System.out.println("integer1 != integer2");
}

Integer integer3 = new Integer(3);
Integer integer4 = new Integer(3);

if (integer3 == integer4) {
System.out.println("integer3 == integer4");
} else {
System.out.println("integer3 != integer4");
}

Integer integer1 = 3 发生了自动装箱,编译器会将其等价转换为 Integer integer1 = Integer.valueOf(3),所以 integer1 == integer2。而通过构造函数创建的 Integer 对象属于不同的对象,指向不同的内存地址,所以 integer3 != integer4

另外,可以通过增加虚拟机的参数 -XX:AutoBoxCacheMax=size 来设置整型缓存的最大值,如 -XX:AutoBoxCacheMax=500 表示-128到500的整型会被缓存。

参考:

I ran into an error when running Remote - SSH in Visual Studio Code on Windows. The error shows that an SSH installation couldn’t be found, but I’ve installed the git client. Finally I found some useful info in the doc:

VS Code will look for the ssh command in the PATH. Failing that, on Windows it will attempt to find ssh.exe in the default Git for Windows install path. You can also specifically tell VS Code where to find the SSH client by adding the remote.SSH.path property to settings.json.

My git client was not installed in the default path, thus VS Code couldn’t find the ssh command. So I added the remote.SSH.path property to settings.json and problem solved.

Reference:

I tried to resize a Client Web Part with non integers as size, but it failed. And that’s why:

1
2
3
4
var regex = RegExp(/(<\s*[Mm]essage\s+[Ss]ender[Ii]d\s*=\s*([\dAaBbCcDdEdFf]{8})(\d{1,3})\s*>[Rr]esize\s*\(\s*(\s*(\d*)\s*([^,\)\s\d]*)\s*,\s*(\d*)\s*([^,\)\s\d]*))?\s*\)\s*<\/\s*[Mm]essage\s*>)/);
var results = regex.exec(e.data);
if (results == null)
return;

The regular expression shows that it doesn’t allow float numbers.

I’m learning how to upgrade SharePoint App, and I met a problem when I added a new list field in the upgrade.

The document mentioned that if you added a field to a content type in the feature, you should add an AddContentTypeField element to the VersionRange section. But there is no ContentType in my app, it only has a ListDefinition. I tried to add an AddContentTypeField, unfortunately it throws exception.

So I tried another way. The document also mentioned that if you have changed a file that is referenced in an elements manifest file, you have to copy the ElementManifest element for the component from the ElementManifests section to the ApplyElementManifests section. When we added a new field to list, the Schema.xml is changed, although it’s not referenced in a ElementManifest, I still copied MyList/Elements.xml to ApplyElementManifests, so it looks like this:

1
2
3
4
5
6
7
8
<UpgradeActions>
<VersionRange>
<ApplyElementManifests>
...
<ElementManifest Location="MyList\Elements.xml" />
</ApplyElementManifests>
</VersionRange>
</UpgradeActions>

And it works. Hope it’s helpful.

Reference:

Issue

Today I met a bug in SharePoint 2013, I failed to resize my app part by using postMessage. Here is my code:

1
2
var message = "<Message senderId=" + senderId + ">" + "resize(" + width + "," + height + ")</Message>";
window.parent.postMessage(message, hostUrl);

It fails to work if I set Chrome Type to None or Border Only. And I found an error message in console:

1
Uncaught TypeError: Cannot read property 'style' of null

Then I located the code in my web part page which throws the error:

1
2
3
4
5
if (resizeWidth)
{
document.getElementById(webPartDivId + '_ChromeTitle').style.cssText = widthCssText;
cssText = 'width:100% !important;'
}

It tries to find the title element and resize it. But document.getElementById(webPartDivId + '_ChromeTitle') returns null if Chrome Type is None or Border Only!
Because the app part doesn’t have a title under these 2 modes. Of course it will throw exception.

Solution

This bug is described here, you can install a patch to fix this bug.

After the patch is installed, you can find that the original code is changed, it will resize the element only if it’s not null:

1
2
3
4
5
6
7
8
9
10
if (resizeWidth)
{
var webPartChromeTitle = document.getElementById(webPartDivId + '_ChromeTitle');
if (null != webPartChromeTitle)
{
webPartChromeTitle.style.cssText = widthCssText;
}

cssText = 'width:100% !important;'
}

Hope it’s helpful.

Reference

Introduction

SharePoint App Model provides a new approach to SharePoint development. And here is the question: where to save app data? There are several ways to save data in an app, you can create a list or connect to a database in Windows Azure or set custom properties in AppManifest.xml. But we can also save data to the property bag of a SharePoint web.

Add property to web

Adding custom property to web is easy. Let’s just see the code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var context = SP.ClientContext.get_current();
var web = context.get_web();

// Add a new property
var props = web.get_allProperties();
props.set_item("MyProperty", "My property value");

// Apply change to web
web.update();
context.load(web);

context.executeQueryAsync(function (sender, args) {
alert("Success.");
}, function (sender, args) {
alert("Request failed.");
});

How do we know “MyProperty” is really added to web? We can check it here: http://your_web/_api/web/AllProperties?$select=MyProperty. The result looks like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?xml version="1.0" encoding="utf-8" ?>
<entry xml:base="http://your_web/test/_api/" xmlns="http://www.w3.org/2005/Atom" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:georss="http://www.georss.org/georss" xmlns:gml="http://www.opengis.net/gml">
<id>http://your_web/_api/web/AllProperties</id>
<category term="SP.PropertyValues" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
<link rel="edit" href="web/AllProperties" />
<title />
<updated>2013-12-04T04:37:07Z</updated>
<author>
<name />;
</author>
<content type="application/xml">
<m:properties>
<d:myproperty>My property value</d:myproperty>
</m:properties>
</content>
</entry>

Read property from web

We have two approaches to read properties from web: props.get_item("PropertyKey") or REST API.

The get_item method

1
2
3
4
5
6
7
8
9
10
11
12
var context = SP.ClientContext.get_current();
var web = context.get_web();

var props = web.get_allProperties();
context.load(props);

context.executeQueryAsync(function (sender, args) {
var prop = props.get_item("MyProperty");
alert(prop);
}, function (sender, args) {
alert("Request failed.");
});

The REST API

1
2
3
4
5
6
7
8
9
10
11
12
13
var executor = new SP.RequestExecutor('http://your_web');
executor.executeAsync({
url: 'http://your_web/_api/web/AllProperties?$select=MyProperty',
method: 'GET',
headers: { "Accept": "application/json; odata=verbose" },
success: function (response) {
var obj = JSON.parse(response.body);
alert(obj.d.MyProperty);
},
error: function (response) {
alert(response.body);
}
});

And here is the json query result, very straightforward:

1
2
3
4
5
6
7
8
9
10
{
"d": {
"__metadata": {
"id": "http://your_web/_api/web/AllProperties",
"uri": "http://your_web/_api/web/AllProperties",
"type": "SP.PropertyValues"
},
"MyProperty": "My property value"
}
}

Reference

0%