Каков аналог для нокаут-записи, который можно вычислить в AngularJS?

Я использую KnockoutJS в своих проектах, но хочу учить AngularJS, поскольку у него много вкусных функций, которых у Knockout нет. Поэтому я заинтересован в перезаписи кода, используя Angular. Но я не понимаю, как делать некоторые простые вещи, которые я использую в Knockout. Например, у нокаута есть функция вычисленных наблюдаемых. Это круто! Я уже нашел, что вместо этого могу использовать простую функцию. Но Knockout предоставляет функцию "write" для вычисленных наблюдаемых, например:

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]);
        }
    });

Этот код в JSFiddle: http://jsfiddle.net/Girafa/QNebV/1/

Этот код позволяет мне обновлять наблюдаемые "first_name" и "last_name" при изменении имени "full_name". Как это можно сделать с помощью AngularJS? Функция с аргументом, проверяемым на существование? Что-то вроде этого?

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

Какова наилучшая практика?

Ответы

Ответ 1

Я нашел такое решение: http://jsfiddle.net/Girafa/V8BNc/

Вместо использования метода angular $watch мы устанавливаем собственный javascript-getter и setter свойства fullName:

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

Думайте, что это более удобно, так как мне не нужно делать никаких специальных наблюдателей в коде. Но я не знаю о поддержке браузером этого решения.

Ответ 2

Извините. Это правда, это проще в нокауте, потому что функция вызывается, тогда как свойство используется в angular. Именно так я могу это решить, но я хотел бы знать, есть ли лучший способ.

Я зафиксировал это время 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];  
    });
});