即时注入指令

时间:2014-02-11 15:29:25

标签: javascript angularjs

所以我有一个指令:

angular.module('mymodule').directive('myNote', function() {
    var fnLink = function(scope, element, attrs){
        console.log('in directive', arguments);
    };

    return {
        restrict: 'E',
        template: [
            '<div class="note" data-id="{{note._id}}">',
                '<span>{{note.content}}</span> ',
            '</div>'
        ].join('\n'), 
        link: fnLink
    };
});

并且,在另一个指令中,管理将出现这些“注释”的容器:

Note.find({
    user: $scope.global.user._id,
    module: $scope.module._id
}).then(function(response) {
    $scope.notes = response;
    angular.forEach($scope.notes, function(note){
            $scope.note = note;
        element.append($('<my-note>'));
    });
    $compile(element)($scope);
});

现在正在按原样呈现HTML; 我有两个问题:

  1. 未运行fnLink功能
  2. 我不知道如何将forEach中的每个音符连接到它自己的指令实例
  3. 更新 设置代码的方式,每个呈现的注释都将绑定到$ scope.notes数组中的最后一个注释。我怎样才能使它们成为个体?

    我接近这完全错了吗? 谢谢

2 个答案:

答案 0 :(得分:2)

你需要$compile元素来连接指令。并将$ scope传递给它:

$compile(element)($scope);

I wrote a blog entry a while back on how $compile works,但基本上它是这样做的:

  1. 从传递给它的元素开始并遍历其所有子元素。
  2. 在每个步骤中查看是否匹配任何指令并设置其链接函数以通过一个函数调用运行,即“编译视图”。
  3. 调用“编译视图”时,将适当的范围传递给每个指令(例如,相同的范围,子范围或隔离的范围)。
  4. 现在已经接通了。

  5. 编辑:跟进您的问题:

      

    我接近这完全错了吗?

    好。说实话?也许?没有看到更多代码就很难说。

    从我读过的内容来看,似乎你有嵌套指令“管理笔记”。一般来说,这可能是错误的做法。

    快速减少控制器,服务和指令以及它们的用途(非常一般):

    • 指令:
      • 设置DOM和Scope之间的绑定。
      • 使用功能创建可重用的视图(部分)。
    • 服务:
      • 用于封装共享逻辑。
      • 用于管理共享数据。
    • 控制器:
      • 用于为视图设置“业务逻辑”。
      • 为视图准备模型。

    指令更多是Angular的“内部运作”。你可以在指令中做很多事情,很容易在指令中混淆你的顾虑。最好是尽量保持简单和重点。例如,可重用的部分,它只是一个模板和一个控制器。或者只是一个链接函数的绑定指令。

    您应该管理服务指令之间的“注释”。您甚至可以将该服务注入到您的指令中,但它允许您将该注意事项与您的指令分开,以使一切更易于测试。

    这里非常紧密地联系在一起:

    让我用自己的代码注释自己的代码:

    //In a directive, so DOM and model
    
    // Data Access
    Note.find({
        // Model
        user: $scope.global.user._id,
        module: $scope.module._id
    }).then(function(response) {
    
        // Model
        $scope.notes = response;
    
        // DOM Manipulation
        angular.forEach($scope.notes, function(note){
            // Model
            $scope.note = note;
    
            // Manual DOM manipulation
            element.append($('<oowli-note>'));
        });
    
        // Manual call to $compile
        $compile(element)($scope);
    });
    

    ..所有在指令中,如上所述,应该限制它的关注点。所以基本上,如果你去测试这个指令,你将会处理

    使用转发器可能会更好吗?

    <oowli-note ng-repeat="note in notes"/>
    

    然后通过服务电话在控制器中获取笔记?

    app.controller('NoteCtrl', function($scope, Note) {
        Note.find($scope.x, $scope.y).then(function(notes) {
           $scope.notes = notes;
        });
    });
    

    但是,我不知道你究竟想要完成什么......所以我只是提出这个建议,希望它有所帮助。

答案 1 :(得分:0)

经过几个小时的调查,我找到了解决这个问题的方法; this talk给了我很多帮助 我需要使用Angular Directive的隔离范围。以下是它的工作原理:

//READER Directive
var initNotes = function($scope, Note, element, $compile){
    Note.find({
        user: $scope.global.user._id,
        module: $scope.module._id
    }).then(function(response) {
        $scope.notes = response;
        angular.forEach($scope.notes, function(note){
            var highlighted = element.find('span.highlighted');
            var html = '<my-note _id="'+note._id+'" content="'+note.content+'"></my-note>';
            highlighted.after($compile(html)($scope));
        });
    });
};

//NOTES Directive
angular.module('oowli').directive('myNote', function() {

    var fnLink = function($scope, element, attrs){
        element.on('keydown', '.note span', noteKeyDown($scope));
        element.on('click', '.edit', editClick($scope));
        element.on('click', '.remove', removeClick($scope));
    };

    return {
        restrict: 'E',
        template: [
            '<div class="note" data-id="{{id}}">',
                '<div class="note-buttons">',
                    '<a href="#" class="glyphicon glyphicon-pencil edit"></a>',
                    '<a href="#" class="glyphicon glyphicon-remove remove"></a>',
                '</div>',
                '<span>{{content}}</span> ',
            '</div>'
        ].join('\n'), 
        scope: {
            id: '=_id',
            content: '@content'
        },
        link: fnLink
    };
});

我传递的指令属性被映射到myNote指令中的范围。