将变量从控制器传递到指令隔离范围的最佳方法,而不将其添加到父级范围

时间:2013-04-13 08:49:49

标签: javascript angularjs angularjs-directive angularjs-scope

很抱歉,如果标题不是最准确的.. 那么我正在尝试做什么以及我背后的理由是什么。我有一个条目列表可能非常庞大,最多400个项目,我从ajax请求获取此列表,现在如果第一个项目具有属性running我想从中提取它列表(使用splice())并将其传递给指令,该指令可以在隔离范围中处理它。为什么?因为正在运行的条目上会有一个计时器,它会使用$timeout每秒为其中一个属性添加+1。

现在我希望它被隔离因为Angular.js filters and functions on scope that is changing every second我不希望过滤器和 not-running 条目列表中的所有内容每秒被调用只是因为某些事情(特别是计时器)在运行的条目上改变了。

现在当我按保存或其他内容时,我想将正在运行的条目放回到条目中,现在只能使用running: false

我知道如何从父级继承对象并在指令上创建一个独立的范围 - http://plnkr.co/edit/zq3urVh5t6N12T5ZrViO?p=preview

以这种方式传递它似乎并不是很理想,但我被告知这很好,没有什么可以反对最佳实践。

现在出现问题/问题

  1. 有没有办法传递“运行”指令而不将其添加到范围内,因为它一旦被复制就几乎没用了
    • 我是否应该寻找一种传递它的方法而不将其添加到范围内?
    • 还是应该在复制后将其删除?
    • 或者我应该离开它,因为它没关系?
  2. 如果使用ajax设置ENTRIES,则无法复制正在运行的那个,因为它尚未设置 - http://plnkr.co/edit/vH3hKbkTkTvcHqykIXDt?p=preview
  3. 谢谢!

2 个答案:

答案 0 :(得分:0)

如果你想传递完整的文字对象,你必须使用'=',但如果你想使用@那么你必须使用$ eval看看工作的小例子

<!doctype html>
<html ng-app="plunker" >
<head>
  <meta charset="utf-8">
  <title>AngularJS Plunker</title>

  <link rel="stylesheet" href="style.css">
  <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.5/angular.min.js"></script>
  <script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
    <input ng-model="obj.name">

    <my-directive obj="obj" title="{{title}}">

      </my-directive>
    <script type="text/javascript">
        var app = angular.module('plunker', []);

        app.controller('MainCtrl', function ($scope) {
            $scope.obj = { name: "John", surname: "Doe" };
            $scope.title = { name: 'abc' };
        });


         app.directive('myDirective', function () {
        return {
            restrict: 'E',
            template: "<div><span>{{obj.name}}<span><span>{{title}}<span></div>",
            replace: true,
            scope: { title: '@', obj: '=' },
            link: function (scope, element, attrs) {
                attrs.$observe('title', function (value) {
                    alert(scope.$eval(value).name);
                })


            }
        }
    })
    </script>
</body>
</html>

答案 1 :(得分:0)

将您的指令更改为具有范围:true - 然后将其隔离但继承父

app.directive('myDirective', function($timeout) {
    return {
    restrict: 'E',
    scope: true,
        link: function(scope, element, attrs) {
            scope.timer = 0;
            $timeout(function tick() {
                scope.timer = scope.timer+1;
                $timeout(tick, 1000);
            });      
        }
    }
})

然后在你的指令中使用它就好像它在父范围内一样!

<my-directive>
  <h4>"running" entry on directive in isolated scope</h4>
  <p>Timer: {{timer}}</p>
  {{ running | json }}<br/>
  <input type="text" ng-model="running.name" />
</my-directive>

http://plnkr.co/edit/f5AzfjoEmRT9P1Dw8REj?p=preview