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 的数据绑定不能正确处理具有属性的对象,而这些属性又具有 属性 同名...