如何在重新渲染后获得指令的最后状态?

时间:2014-07-11 09:17:34

标签: angularjs angularjs-directive angularjs-scope

如何在重新渲染指令(链接功能再次执行)后获取指令的最后状态?通过 state 我指的是一些由指令本身设置的数据,而不是通过属性传递的。

我创建了一个简单的示例here on jsFiddle。我想要实现的是在单击tab2并返回到tab1时在tab1上看到相同的值。

HTML

<div ng-app="myApp">
    <nav ng-init=" selected = 'tab1' ">
        <a href="" ng-click=" selected = 'tab1' ">tab1</a> | 
        <a href="" ng-click=" selected = 'tab2' ">tab2</a>
    </nav>
    {{selected}} is selected
    <div ng-if="selected == 'tab1' ">
        remember the values and go to tab2
        <div my-directive></div>
        <div my-directive></div>
    </div>
    <div ng-if="selected == 'tab2' ">
        go back to tab1 and see how data changed
    </div>
</div>

JS

(function() {
    var myApp = angular.module('myApp', ['myDirectiveModule']);
})();


(function(angular) {
    angular.module('myDirectiveModule', [])

    .directive('myDirective', 
        function() {

            return {
                restrict: 'A',
                scope: true,
                template: 'this is directive, data is {{directiveData}}',
                link: function($scope, iElm, iAttrs, controller) {
                    console.log('link function is executing');
                    $scope.directiveData = $scope.directiveData || Math.floor((Math.random() * 100) + 1);
                }
            };
        }
    );

})(angular);

我想到了不同的解决方案,但似乎都没有,例如:

  • 使用service来存储数据(在数组中因为可以有更多的myDirective实例),但指令如何知道要求的数组索引?
  • 使用controller内部指令,但问题与前一种情况一样。当页面上没有显示指令时,控制器可能也会丢失
  • 使用一些父scope或父controller来跟踪数据,但是我不能强迫用户在他们想要使用指令的地方创建控制器,而不是从架构角度看的好解决方案。 myDirectivemyDirectiveModule应该单独处理所有内容

1 个答案:

答案 0 :(得分:0)

我认为最简单的解决方案是使用ngShow代替ngIf。这将使用CSS呈现或隐藏元素,而不是在DOM中重新编译新元素。

以下是服务如何运作的示例:

.service('data', function() {
    this.data = {};
    this.generateData = function(id){ 
        if (this.data[id] !== undefined)
            return this.data[id];
        else     
            return this.data[id] = Math.floor((Math.random() * 100) + 1);
    };
})

在链接功能中:

$scope.directiveData = data.generateData(iAttrs.id);

FIDDLE

编辑:

您可以采取以下措施来获取元素的唯一ID,而无需明确指定它:

function getIndex (node) {
      var parent=node.parentElement||node.parentNode, i=-1, child;
      while (parent && (child=parent.childNodes[++i])) if (child==node) return i;
      return -1;
}

function getPath (node) {
      var parent, path=[], index=getIndex(node);
      (parent=node.parentElement||node.parentNode) && (path=getPath(parent));
      index > -1 && path.push(index);
      return path;
}

我是从here得到的。使用相同的服务,但改变:

$scope.directiveData = data.generateData(getPath(iElm[0]));

应该有效。这种方法可能存在缺陷,但我无法想象它可能是什么。使用显式id就是我要做的。