简体   繁体   中英

What is the analog for Knockout's writable computed observable in AngularJS?

I use KnockoutJS in my projects, but want to learn AngularJS as it has a lot of tasty features that Knockout doesn't have. So I'm interested in rewriting some of my code using Angular. But I don't understand how to do some simple things that I use in Knockout. For example, Knockout has a feature of computed observables. It's cool! I've already found that I can use a simple function instead. But Knockout provides "write" function to a computed observables, like:

var first_name = ko.observable('John'),
    last_name = ko.observable('Smith'),
    full_name = ko.computed({
        read: function(){
            return first_name() + ' ' + last_name();
        },
        write: function(new_value){
            var matches = new_value.match(/^(\w+)\s+(\w+)/);

            first_name(matches[1]);
            last_name(matches[2]);
        }
    });

This code on JSFiddle: http://jsfiddle.net/Girafa/QNebV/1/

This code allows me to update the "first_name" and "last_name" observables when I change the "full_name" one. How it can be done using AngularJS? A function with an argument being checked for existence? Something like this?

first_name = 'John';
last_name = 'Smith';
full_name = function(value){
    if (typeof value != 'undefined')
    {
        // do the same as in the Knockout's write function
    }
    else
    {
        // do the same as in the Knockout's read function
    }
}

What is the best practice?

I've found such a solution: http://jsfiddle.net/Girafa/V8BNc/

Instead of using angular $watch method, we set native javascript getter and setter of the fullName property:

Object.defineProperty($scope, 'fullName', {
    get: function(){
        #...
    },
    set: function(newValue){
        #...
    }
})

Think this is more convenient as I don't need to make any special watchers in the code. But I don't know about browser support of this solution.

Sorry about that. It's true, this is simpler in knockout because a function is called whereas a property is used in angular. This is the way I could resolve it, but I would like to know if there is a better way.

I fixed this time Plunker

app.controller('Ctrl', function($scope) {
    $scope.firstName = 'John';
    $scope.lastName  = 'Smith';

    $scope.getFullName = function() {
        $scope.fullName = $scope.firstName + ' ' + $scope.lastName;
        return $scope.fullName;
    }

    $scope.$watch('fullName', function(newValue, oldValue) {
        var names = newValue.split(' ');
        $scope.firstName = names[0];
        $scope.lastName  = names[1];  
    });
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM