2014-04-08 17 views
0

我是AngularJS的新手,已經耗盡Google和egghead.io視頻上的隔離範圍試圖解決這個問題 - 對不起,如果這已被覆蓋之前,但我需要一些幫助。重構指令使控制器方法在維護雙向綁定時只調用一次?

我有一個指令(<span status-label>),它使用隔離範圍將數據屬性(item=)中的人員對象($scope.data.jack)傳遞給模板。

在該指令的controller函數中,我定義了一個函數來計算人物對象的狀態並將其返回(get_status(item))。根據返回的狀態,指令模板發生變化(對於示例而言,get_status函數極其簡化)。

在下面的簡化示例中,我通過`ng-show``在模板內部調用get_status函數,每個狀態一次,這意味着隨着狀態數量的增加,函數的次數也會增加必須被調用。這看起來效率很低。

如何重構此示例以便get_status只需要調用一次,同時保持內部人員對象與父人員對象之間的雙向綁定?我嘗試在指令隔離範圍上使用'&'指示符來創建映射到get_status(item)的結果的模板變量,但沒有運氣。提前致謝。

Plunkr:http://plnkr.co/edit/lDkTcA?p=info

指令HTML:

<div ng-controller='BaseController'> 
    <p>{{ data.jill.name }}: <span status-label item='data.jill'></span></p> 
    <p>{{ data.jack.name }}: <span status-label item='data.jack'></span></p> 
</div> 

BaseController

angular.module('familyApp').controller('BaseController', 
    function ($scope) { 
    $scope.data = { 
     jack: {name: 'Jack', age: 40, flagged: false},    
     jill: {name: 'Jill', age: 30, flagged: true} 
    }; 
    }); 

statusLabel指令

angular.module('familyApp').directive('statusLabel', 
    function ($compile, $parse) { 
     return { 
      controller: function ($scope) { 
       $scope.get_status = function (item) { 
       if (item.flagged === true) { 
        return 1; 
       } else { 
        return 0; 
       } 
       };       
      }, 
      scope: { 
       'item': '=', 
      }, 
      template: '<div ng-show="get_status(item) == 1">Flagged (<a href ng-click="item.flagged = false">Unflag</a>)</div><div ng-show="get_status(item) == 0">Clean (<a href ng-click="item.flagged = true">Flag</a>)</div>' 
     }; 
    }); 

回答

0

我不確定這是否會提供更好的性能,但您可以在get_status函數的值上創建監視。

$scope.$watch(function() { 
    return $scope.get_status($scope.item); 
}, function(newValue, oldValue) { 
    $scope.status = newValue; 
}); 

然後在您的模板中使用此值。

template: '<div ng-show="status === 1">Flagged (<a href ng-click="item.flagged = false">Unflag</a>)</div><div ng-show="status === 0">Clean (<a href ng-click="item.flagged = true">Flag</a>)</div>' 

我更新了普拉克這裏:http://plnkr.co/edit/l6Osy43zInSE66ixq9Nj?p=preview

0

我想這種方法會更簡單。基本上引入另一個範圍變量,將其設置在get_status函數中,然後在模板中根據需要引用它。

function ($compile, $parse) { 
     return { 
     controller: function ($scope) { 
      **$scope.isFlagged = getstatus($scope.item);** 

      function getstatus(item) { 
      if (item.flagged === true) { 
       return true; 

      } else { 
       return false; 

      } 

      };       
     }, 
     scope: { 
      'item': '=', 
     }, 
     template: '<div ng-show="isFlagged">Flagged (<a href ng-click="item.flagged = false">Unflag</a>)</div><div ng-show="!isFlagged">Clean (<a href ng-click="item.flagged = true">Flag</a>)</div>' 
    }; 
}); 

請注意,我簡化了原來的邏輯ng-show以及...小提琴是在這裏:http://jsfiddle.net/rem70/Nrz5C/

相關問題