自定义指令范围与控制器在同一元素中

时间:2014-10-08 10:50:29

标签: javascript html5 angularjs controllers

所以我在尝试将一些有效的1.2.16代码迁移到1.3.0时遇到了这个问题。我已阅读发行说明,但未能确切了解导致问题的原因

它似乎归结为我试图通过指令将自定义范围分配给定义为控制器的HTML元素。这在过去运作良好,我不知道如何解决它。

我的指令使事情“可拖动” - 它将我的模型中的数据分配给原生HTML5拖放的元素。下降。我的指示:

app.directive('draggable', function() {
    return{
        scope: {
            data : '=data'
        },

        link : function(scope, element) {
        // this gives us the native JS object
        var el = element[0];

        el.draggable = true;

        el.addEventListener('dragstart', function(e) {
            e.dataTransfer.effectAllowed = 'move';

            e.dataTransfer.setData('Text', JSON.stringify(scope.data));
            this.classList.add('drag');
            return false;
        }, false);

        el.addEventListener('dragend', function(e) {
            this.classList.remove('drag');
            return false;
        }, false);
    }
    }
});

我是如何使用它的:

`<div ng:repeat="step in pass.steps" ng:controller="StepEditorController" class="stepcontainer" draggable data="step">`

我需要使用该指令来使整个'step'元素可拖动。但是现在,我在指令中指定的自定义范围似乎给了我麻烦。我需要自定义范围才能获取该数据变量以定义正在拖动的数据。

再次,这曾经工作正常,但现在我得到multidir error,因为多个控制器正在尝试分配范围。

任何提示?这真让我抓狂。

1 个答案:

答案 0 :(得分:0)

您似乎并不需要创建隔离范围,只需使用属性名称来查找范围内的属性。

为了使您的指令与您定义它的元素具有相同的作用域,请从指令定义中删除作用域对象(或使用作用域:true)。

然后确保您引用了链接功能中的属性

link : function(scope, element, attributes) {...}

现在,您可以使用您在属性中指定的属性名来访问范围对象中的变量,而不是像以前一样使用指令的隔离范围上的值

e.dataTransfer.setData('Text', JSON.stringify(scope[attributes.data]));
// attributes.data is the name of the property on the scope

以下是所有代码:

app.directive('draggable', function() {
    return{
        //scope: { // omit the scope definition so you have the scope of the element itself
        //    data : '=data'
        //},

        link : function(scope, element, attributes) { // you now need to use the attributes
        // this gives us the native JS object
        var el = element[0];

        el.draggable = true;

        el.addEventListener('dragstart', function(e) {
            e.dataTransfer.effectAllowed = 'move';

            // take the data from the scope directly using the attribute as the property name
            e.dataTransfer.setData('Text', JSON.stringify(scope[attributes.data])); 
            this.classList.add('drag');
            return false;
        }, false);

        el.addEventListener('dragend', function(e) {
            this.classList.remove('drag');
            return false;
        }, false);
    }
    }
});