21

试图更深入地了解 Angular 如何处理数据绑定并更好地理解它,但有一件事我很难理解 -

在 Knockout 中,我使用计算来跟踪属性的更改。在 Angular 中,它将这个逻辑移动到视图中,这对我来说是微不足道的,但如果这是我理解的方式。

我的问题是,当我使用 Breeze/Angular 初始化新实体时,如何创建类似计算的属性,当实体属性发生更改时通知这些属性?

myEntity.fullName = ko.computed(function () {
    return myEntity.firstName + ' ' + myEntity.LastName;
});

在 Angular 中相当于

myEntity.fullName = function () {
    return myEntity.firstName + ' ' + myEntity.LastName;
};

这是否正确跟踪实体?

4

2 回答 2

18

简单地将其设为函数是正确的。如果您的实体如图所示被添加到$scope,那么您将像这样访问该属性:

<span class="fullname">{{ user.fullName() }}</span>

每当 Angular 运行一个$digest循环时,它都会检查绑定属性的变化。在这种情况下,这意味着它将调用该fullName()函数并检查结果是否已更改。如果有,任何$watch附加到该项目的东西(包括简单绑定)都将收到更改通知。

然而,这种技术的一个警告是确保在您的函数中执行的操作相对较快,并且也没有副作用。像这样的绑定函数将在整个应用程序中多次调用。

如果您需要更复杂的功能,最好在控制器中处理它,并在对象更改时手动更新对象的属性。

于 2013-08-14T02:56:16.440 回答
0

我在以下网站上找到了答案。如果你不做类似的事情,你会发现所有函数都是在摘要阶段运行的,而不是由依赖的 observable 或属性的变化触发的。下面的解决方案允许您仅在函数使用的值发生更改时触发该函数。

http://www.jomendez.com/2015/02/06/knockoutjs-computed-equivalent-angularjs/

解释如何在 knockoutjs 中复制订阅和计算功能

var myViewModel = {
    personName: ko.observable('Bob')
};
myViewModel.personName.subscribe(function(oldValue) {
    alert("The person's previous name is " + oldValue);
}, null, "beforeChange");

这是我的研究结果(这是 AngularJs 等效项)使用 $scope.$watch 方法查看 AngularJs 生命周期https://docs.angularjs.org/guide/scope

$scope.myViewModel = {
    personName: 'Bob'
};
$scope.$watch(‘myViewModel.personName’, function(newValue, oldValue){
    //we are able to have both the old and the new value
    alert("The person's previous name is " + oldValue);
});

//knockout computed
var isVendorLoading = ko.observable(),
isCustomerLoading = ko.observable(),
isProgramLoading = ko.observable(),
isWaiting = ko.observable();

var isDataLoading = ko.computed(function () {
    return isVendorLoading() || isCustomerLoading() || isProgramLoading() || isPositionLoading() || isWaiting();     
});

这是计算的 KnockoutJs 的 AngularJs 等效项:

$scope.isDataLoading = false;
$scope.$watch(
    function (scope) {
        //those are the variables to watch
        return { isVendorLoading: scope.isVendorLoading, isCustomerLoading: scope.isCustomerLoading, isProgramLoading: scope.isProgramLoading, isWaiting: scope.isWaiting };
    },
    function (obj, oldObj) {
         $timeout(function () {
              //$timeout used to safely include the asignation inside the angular digest processs
              $scope.isDataLoading = obj.isVendorLoading || obj.isCustomerLoading || obj.isProgramLoading || obj.isPositionLoading || obj.isWaiting;
         });
    },
    true
);
于 2015-10-07T23:31:03.503 回答