2016-04-10 4 views
0

Es muss etwas sein, das ich überwache, aber wenn ich eine Eigenschaft (ein Objekt) eines Observable ändert, wird das UI zum ersten Mal wie erwartet aktualisiert. Aber das zweite Mal sehe ich keine Änderung, obwohl das Observable geändert wurde und eine Benachrichtigung gesendet hat (ich sehe das in der receiveNotification-Funktion). Siehe Code unten, die Änderung erfolgt über einen Dialog und die UnitTap-Funktion. Was fehlt mir hier?NativeScript UI reagiert nicht auf propertyChange von Observable bei wiederholten Änderungen

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> 

Antwort

0

Nun gut, ich bin meine eigene Gummi-Ente ...

Blick auf diese beiden Beispiele und die schockierende Unterschied sehen:

obs.xml Version 1:

<Page loaded="loaded"> 
    <StackLayout> 
    <TextField text="{{ item.seconds }}"/> 
    <TextField text="{{ item.secondsobject.seconds}}"/> 
    <Button text="Increase" tap="increaseSeconds"/> 
    </StackLayout> 
</Page> 

obs. js Version 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 Version 2:

<Page loaded="loaded"> 
    <StackLayout> 
    <TextField text="{{ item.seconds }}"/> 
    <TextField text="{{ item.secondsobject.secondsobject}}"/> 
    <Button text="Increase" tap="increaseSeconds"/> 
    </StackLayout> 
</Page> 

obs.js Version 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}); 
}; 

Version 1 funktioniert wie vorgesehen, werden beiden Felder mit dem neuen Wert auf jeder Taste klicken aktualisiert. Version 2 aktualisiert nur das Feld 'item.secondsobject.secondsobject' beim ersten Klick und ignoriert den aktualisierten Wert bei aufeinanderfolgenden Klicks. Offenbar behandelt Nativescript Databinding Objekte nicht richtig, die Eigenschaften haben, die wiederum auch eine Eigenschaft mit dem gleichen Namen haben ...

+0

Das klingt wirklich wie ein Fehler - können Sie ein Problem in [GitHub] (https://github.com/NativeScript/NativeScript/issues) so öffnen dass das Team es genauer unter die Lupe nehmen kann. –

+0

Alexander, ich hatte in den letzten Tagen nicht die Zeit dazu, aber ich habe es gerade getan. – ProGig

0

Ist es möglich, dass die product Objekt, das Sie aus dem nav-Kontext immer ist nicht beobachtbar sich. Ich kann sehen, dass Sie erstellen und Observable für die pageData, aber das wird nicht automatisch alle seine Feld beobachtbar machen auch. Hoffe, dass hilft.

+0

Danke Alexander, aber (leider) ist das nicht das Problem. Das als Kontext übergebene Produktobjekt ist ein Observable. Ich überprüfte und überprüfte das. Außerdem ist das Merkwürdige, dass die UI beim ersten Mal aktualisiert wird, wenn das Einheitsfeld geändert wird. Die einzige Sache, die sich von einem Nicht-Observablen zu einem Observablen ändert, ist das Einheitsobjekt, das als Eigenschaft des Produkts ersetzt wird. Aber ich habe auch versucht, die Unit-Eigenschaft mit einem einfachen Objekt zu aktualisieren. Das hat den Trick nicht gemacht. – ProGig

+0

Entschuldigung. Kannst du das XML auch posten? –

+0

Sicher. Ich habe den ursprünglichen Post aktualisiert. Das Seltsame ist, dass ich ** die Benachrichtigung der Eigenschaft sehe. Ändern – ProGig