NativeScript UI 在重复更改时不响应 Observable 的 propertyChange
NativeScript UI doesn't respond to propertyChange of Observable when repeating changes
它一定是我监督的东西,但是当我第一次更改 Observable 的 属性(这是一个对象)时,UI 会按预期更新。但是第二次我没有看到任何变化,尽管 observable 已更改并发送了通知(我在 receiveNotification 函数中看到了这一点)。
请参阅下面的代码,更改是通过对话框和 unitTap 函数进行的。我在这里错过了什么?
var pageData;
function setPageData (product) {
pageData = new Observable({
units: restClientUnits.viewModelArray,
vatpercentages: restClientVatPercentages.viewModelArray,
product: product
});
loadLists();
}
function receiveNotification(args) {
console.log("Notification received...");
console.log(args.propertyName);
console.log(args.value.unit);
}
exports.loaded = function(args) {
var page = args.object;
var product = page.navigationContext;
//Extra listener just to check if notification is send
product.addEventListener(Observable.propertyChangeEvent, receiveNotification, this);
setPageData(product);
page.bindingContext = pageData;
};
exports.unitTap = function() {
var unitNames = [];
pageData.get("units").forEach(function(unit) {
unitNames.push(unit.get("unit"));
});
dialogs.action({
message: "Select unit",
cancelButtonText: "Cancel",
actions: unitNames,
}).then(function (result) {
pageData.get("units").forEach(function(obj) {
if (obj.unit === result) {
pageData.get("product").set("unit", obj);
}
});
console.log("New set unit: " + pageData.get("product").get("unit").unit);
console.log("Dialog result: " + result)
});
};
<Page.actionBar>
<ActionBar title="Products">
<NavigationButton text="go back" android.systemIcon = "ic_menu_back" tap="goBack"/>
<ActionBar.actionItems>
<ActionItem text="Save" position="right" tap="save"/>
</ActionBar.actionItems>
</ActionBar>
</Page.actionBar>
<StackLayout>
<GridLayout cols="*" rows="auto, auto">
<Label text="productnaam: " cssClass="field-title" />
<TextField text="{{ product.productName }}" cssClass="field" row="1" col="1" />
</GridLayout>
<GridLayout cols="*" rows="auto, auto">
<Label text="beschrijving: " cssClass="field-title" />
<TextView text="{{ product.description }}" cssClass="field" row="1" col="1" />
</GridLayout>
<GridLayout cols="*" rows="auto, auto">
<Label text="Prijs per eenheid: " cssClass="field-title"/>
<TextField text="{{ product.unitPrice }}" cssClass="field" row="1" col="1"/>
</GridLayout>
<GridLayout cols="*" rows="auto, auto">
<Label text="eenheid: " col="0" cssClass="field-title"/>
<TextField text="{{ product.unit.unit }}" cssClass="field" row="1" col="1" editable="false" tap="unitTap"/>
</GridLayout>
<GridLayout cols="*" rows="auto, auto">
<Label text="btw percentage: " cssClass="field-title"/>
<TextField text="{{ product.vatPercentage.vatPercentage }}" cssClass="field" row="1" col="1" tap="showModal"/>
</GridLayout>
</StackLayout>
您从导航上下文中获取的 product
对象是否有可能本身不是可观察对象。我可以看到您正在为 pageData
创建和 Observable
但这不会自动使其所有字段也可观察。
希望对您有所帮助。
好吧好吧,我是我自己的橡皮鸭...
看看这两个例子,就会发现惊人的区别:
obs.xml 版本 1:
<Page loaded="loaded">
<StackLayout>
<TextField text="{{ item.seconds }}"/>
<TextField text="{{ item.secondsobject.seconds}}"/>
<Button text="Increase" tap="increaseSeconds"/>
</StackLayout>
</Page>
obs.js 版本 1:
var Observable = require("data/observable").Observable;
var pageData = new Observable({
item: new Observable({seconds: 1, secondsobject: {seconds: 1}})
});
var page;
exports.loaded = function(args) {
page = args.object;
page.bindingContext = pageData;
};
exports.increaseSeconds = function() {
pageData.item.set("seconds", pageData.item.seconds + 1);
var newValue = pageData.item.secondsobject.seconds + 1;
pageData.item.set("secondsobject",{seconds: newValue});
};
obs.xml 版本 2:
<Page loaded="loaded">
<StackLayout>
<TextField text="{{ item.seconds }}"/>
<TextField text="{{ item.secondsobject.secondsobject}}"/>
<Button text="Increase" tap="increaseSeconds"/>
</StackLayout>
</Page>
obs.js 版本 2:
var Observable = require("data/observable").Observable;
var pageData = new Observable({
item: new Observable({seconds: 1, secondsobject: {secondsobject: 1}})
});
var page;
exports.loaded = function(args) {
page = args.object;
page.bindingContext = pageData;
};
exports.increaseSeconds = function() {
pageData.item.set("seconds", pageData.item.seconds + 1);
var newValue = pageData.item.secondsobject.secondsobject + 1;
pageData.item.set("secondsobject",{secondsobject: newValue});
};
版本 1 按预期工作,每次单击按钮时,两个字段都会更新为新值。版本 2 仅在第一次点击时更新字段 'item.secondsobject.secondsobject',而忽略连续点击时的更新值。
很明显,Nativescript 的数据绑定不能正确处理具有属性的对象,而这些属性又具有 属性 同名...
它一定是我监督的东西,但是当我第一次更改 Observable 的 属性(这是一个对象)时,UI 会按预期更新。但是第二次我没有看到任何变化,尽管 observable 已更改并发送了通知(我在 receiveNotification 函数中看到了这一点)。 请参阅下面的代码,更改是通过对话框和 unitTap 函数进行的。我在这里错过了什么?
var pageData;
function setPageData (product) {
pageData = new Observable({
units: restClientUnits.viewModelArray,
vatpercentages: restClientVatPercentages.viewModelArray,
product: product
});
loadLists();
}
function receiveNotification(args) {
console.log("Notification received...");
console.log(args.propertyName);
console.log(args.value.unit);
}
exports.loaded = function(args) {
var page = args.object;
var product = page.navigationContext;
//Extra listener just to check if notification is send
product.addEventListener(Observable.propertyChangeEvent, receiveNotification, this);
setPageData(product);
page.bindingContext = pageData;
};
exports.unitTap = function() {
var unitNames = [];
pageData.get("units").forEach(function(unit) {
unitNames.push(unit.get("unit"));
});
dialogs.action({
message: "Select unit",
cancelButtonText: "Cancel",
actions: unitNames,
}).then(function (result) {
pageData.get("units").forEach(function(obj) {
if (obj.unit === result) {
pageData.get("product").set("unit", obj);
}
});
console.log("New set unit: " + pageData.get("product").get("unit").unit);
console.log("Dialog result: " + result)
});
};
<Page.actionBar>
<ActionBar title="Products">
<NavigationButton text="go back" android.systemIcon = "ic_menu_back" tap="goBack"/>
<ActionBar.actionItems>
<ActionItem text="Save" position="right" tap="save"/>
</ActionBar.actionItems>
</ActionBar>
</Page.actionBar>
<StackLayout>
<GridLayout cols="*" rows="auto, auto">
<Label text="productnaam: " cssClass="field-title" />
<TextField text="{{ product.productName }}" cssClass="field" row="1" col="1" />
</GridLayout>
<GridLayout cols="*" rows="auto, auto">
<Label text="beschrijving: " cssClass="field-title" />
<TextView text="{{ product.description }}" cssClass="field" row="1" col="1" />
</GridLayout>
<GridLayout cols="*" rows="auto, auto">
<Label text="Prijs per eenheid: " cssClass="field-title"/>
<TextField text="{{ product.unitPrice }}" cssClass="field" row="1" col="1"/>
</GridLayout>
<GridLayout cols="*" rows="auto, auto">
<Label text="eenheid: " col="0" cssClass="field-title"/>
<TextField text="{{ product.unit.unit }}" cssClass="field" row="1" col="1" editable="false" tap="unitTap"/>
</GridLayout>
<GridLayout cols="*" rows="auto, auto">
<Label text="btw percentage: " cssClass="field-title"/>
<TextField text="{{ product.vatPercentage.vatPercentage }}" cssClass="field" row="1" col="1" tap="showModal"/>
</GridLayout>
</StackLayout>
您从导航上下文中获取的 product
对象是否有可能本身不是可观察对象。我可以看到您正在为 pageData
创建和 Observable
但这不会自动使其所有字段也可观察。
希望对您有所帮助。
好吧好吧,我是我自己的橡皮鸭...
看看这两个例子,就会发现惊人的区别:
obs.xml 版本 1:
<Page loaded="loaded">
<StackLayout>
<TextField text="{{ item.seconds }}"/>
<TextField text="{{ item.secondsobject.seconds}}"/>
<Button text="Increase" tap="increaseSeconds"/>
</StackLayout>
</Page>
obs.js 版本 1:
var Observable = require("data/observable").Observable;
var pageData = new Observable({
item: new Observable({seconds: 1, secondsobject: {seconds: 1}})
});
var page;
exports.loaded = function(args) {
page = args.object;
page.bindingContext = pageData;
};
exports.increaseSeconds = function() {
pageData.item.set("seconds", pageData.item.seconds + 1);
var newValue = pageData.item.secondsobject.seconds + 1;
pageData.item.set("secondsobject",{seconds: newValue});
};
obs.xml 版本 2:
<Page loaded="loaded">
<StackLayout>
<TextField text="{{ item.seconds }}"/>
<TextField text="{{ item.secondsobject.secondsobject}}"/>
<Button text="Increase" tap="increaseSeconds"/>
</StackLayout>
</Page>
obs.js 版本 2:
var Observable = require("data/observable").Observable;
var pageData = new Observable({
item: new Observable({seconds: 1, secondsobject: {secondsobject: 1}})
});
var page;
exports.loaded = function(args) {
page = args.object;
page.bindingContext = pageData;
};
exports.increaseSeconds = function() {
pageData.item.set("seconds", pageData.item.seconds + 1);
var newValue = pageData.item.secondsobject.secondsobject + 1;
pageData.item.set("secondsobject",{secondsobject: newValue});
};
版本 1 按预期工作,每次单击按钮时,两个字段都会更新为新值。版本 2 仅在第一次点击时更新字段 'item.secondsobject.secondsobject',而忽略连续点击时的更新值。 很明显,Nativescript 的数据绑定不能正确处理具有属性的对象,而这些属性又具有 属性 同名...