NativeScript UI 在重复更改时不响应属性更改可观察对象



它一定是我监督的东西,但当我第一次更改Observable的属性(它是一个对象)时,UI会按预期更新。但第二次我没有看到任何变化,尽管可观察到的内容发生了变化,并发送了通知(我在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>

您从nav上下文中获得的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.secondsoject.secondsobject",而在连续单击时忽略更新的值。显然,Nativescript的数据绑定无法正确处理具有属性的对象,而这些属性又具有相同名称的属性。。。

最新更新