I want to bind Angular model to a Knockout component. It's working - when the Angular model changes the Knockout binding applies. But the problem is in the opposite direction - I want the Angular model to update when the Knockout component changes, and do so without touching the component (it mustn't know about the Angular wrapper). The target - using Angular to build a rapid prototyping framework around KO components, which are being used in other environments too. The KO components can and should share models (which come from the Angular wrapper) therefore this question.

EDIT: Here is a jsFiddle example to showcase what I'm trying to achieve. Its a simplification because in real-world KO components will use internal VM's which will be difficult to $watch. But even here I don't get why the $watch doesn't work.

var sharedData = {
    personName: "alex",
    personAge: "32"
};


function WrapperCtrl($scope){
    $.each(sharedData, function(key, value) {
        sharedData[key] = (typeof value !== "function") ? ko.observable(value) : value;
    });

    $scope.wrapData = sharedData;

    ko.applyBindings(sharedData, document.getElementById("ko_1"));  
    ko.applyBindings(sharedData, document.getElementById("ko_2"));  

    $scope.$watch(
        function () {
            return sharedData.personName();
        }, 
        function(newValue, oldValue) {
            console.log("change");
        }
    );

    $scope.doSomething = function(){
        console.log("before angular function: ", $scope.wrapData.personName(),    $scope.wrapData.personAge())
        sharedData.personName('Bob').personAge(41);
         console.log("after angular function: ", $scope.wrapData.personName(), $scope.wrapData.personAge())
    };
}


function doSomething() {

    console.log("before knockout function", sharedData.personName(), sharedData.personAge())
    sharedData.personName('Mary').personAge(25);
    console.log("after knockout function", sharedData.personName(), sharedData.personAge())
}
有帮助吗?

解决方案

If you aren't allowed to directly insert angular bindings into your components, then you won't be able to fire off your digest cycle, and so angular will have no idea your data source has updated. One way of tackling this is to periodically call $apply, which will update your model with any external changes, like this:

    setInterval($scope.$apply, 500);

http://jsfiddle.net/HmcnB/11/

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top