在范围变量更改后重新评估传递给指令的属性

时间:2014-11-21 15:26:21

标签: javascript angularjs angularjs-directive angularjs-ng-repeat

我在ng-repeat中生成了一系列元素:

<tr ng-repeat="index in elements">
  <td ng-click="doSomething(index)" my-tooltip tooltip="isInBasket(index.id) && 'REMOVE FROM BASKET' || 'ADD TO BASKET'" ></td>
</tr>

指令MyTooltip期望传递给tooltip属性的值 这将是第一次工作,这意味着执行ng-repeat时。工具提示的值为&#34;从篮子中取出&#34;如果元素已经在篮子中并且值为&#34;添加到篮子&#34;除此以外。

该功能定义如下:

$scope.isInBasket = (id){
  return _.contains($scope.basket, id)
}

现在,我的代码的其他部分将更改$scope.basket,所以我认为isInBasket会在$scope.basket发生更改时重新评估,从而更改传递给的值tooltip属性。

指令

angular.module("tooltips", [])
    .directive("myTooltip", ($parse, $rootScope, $state){
      return {  
        restrict: 'A',
        priority: 999,
        link: function(scope, elm, attrs) {
          tooltip = scope.$eval(attrs.tooltip);
          // .... 
        }
      }
    })

但这不起作用,我很确定我做错了什么或者我错过了什么。

2 个答案:

答案 0 :(得分:1)

您是否正在创建隔离范围?如果是,则需要在您的范围内声明: { 工具提示:'&amp;' }

我认为问题在于你绑定了一个布尔值,因为不可置换会破坏双重绑定,但老实说不确定你是如何使用工具提示指令的

尝试使用您的指令:

angular.module("tooltips", [])
  .directive("myTooltip", ($parse, $rootScope, $state){
    return { 
      scope: { tooltip: "=" } //you could try also "&"
      restrict: 'A',
      priority: 999    
    }
})

好的,如果您尝试分配如下的值:

var tooltip = {dock: scope.$eval(attrs.tooltip)};

或     var tooltip = element.scope()[attrs.tootip];

我的意思是我知道绑定对于一个对象非常重要。

如果这没有帮助你可以用手表绑定它,那应该这样做:

link: function(scope, elm, attrs) {
  var tooltip = element.scope()[attrs.tootip];

  scope.$watch(function () {
    return scope.attrs.tooltip; // i dont know what changes in your app
  }, function() {
    return  tooltip();
  }, true);

答案 1 :(得分:0)

使用tooltip="{{isInBasket(index.id) && 'REMOVE FROM BASKET' || 'ADD TO BASKET'}}"

请参阅下文

var app = angular.module('plunker', ['ui.bootstrap']);

app.controller('MainCtrl', function($scope) {
  $scope.name = 'World';

  $scope.elements = [{
    id: 0,
    name: "banana"
  }, {
    id: 1,
    name: "pear"
  }, {
    id: 2,
    name: "apple"
  }]


  $scope.basket = [];
  $scope.basket.push($scope.elements[0].id)
  $scope.isInBasket = function(id) {

    return _.contains($scope.basket, id)

  }

  $scope.doSomething = function(item) {

    if (_.contains($scope.basket, item.id)) {

      $scope.basket = _.without($scope.basket, item.id)

    } else {
      $scope.basket.push(item.id)
    }
  }
});
tr {
  border: 1px solid grey;
}
<html ng-app="plunker">

<head>
  <meta charset="utf-8" />
  <title>AngularJS Plunker</title>
  <link data-require="bootstrap-css@3.1.*" data-semver="3.1.1" rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" />
  <script>
    document.write('<base href="' + document.location + '" />');
  </script>
  <link rel="stylesheet" href="style.css" />
  <script data-require="angular.js@1.2.x" src="https://code.angularjs.org/1.2.25/angular.js" data-semver="1.2.25"></script>
  <script data-require="ui-bootstrap@*" data-semver="0.12.0" src="http://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.12.0.min.js"></script>
  <script data-require="lo-dash@*" data-semver="2.4.1" src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.1/lodash.js"></script>
  <script src="app.js"></script>
</head>

<body ng-controller="MainCtrl">
  <h1>Hello {{name}}!</h1>
  Basket : {{basket | json }}
  <div class="container">
    <table>
      <tbody>
        <tr ng-repeat="index in elements">
          <td ng-click="doSomething(index)" tooltip="{{isInBasket(index.id) && 'REMOVE FROM BASKET' || 'ADD TO BASKET'}}" style="padding-left:150px">
            {{index.id}}
          </td>
        </tr>
      </tbody>
    </table>
  </div>
</body>

</html>