与控制器在同一元素中的自定义指令作用域

Custom directive scope in same element as controller

本文关键字:自定义 指令 作用域 元素 控制器      更新时间:2023-09-26

所以我在尝试将一些正在工作的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"元素可拖动。但现在,我在指令中指定的自定义范围似乎给我带来了麻烦。我需要自定义作用域来获取数据变量,以定义要拖动的数据。

同样,这以前工作得很好,但现在我遇到了一个多维错误,因为多个控制器正在尝试分配范围。

有什么提示吗?这简直把我逼疯了。

似乎不需要创建隔离作用域,只需使用属性名称即可在作用域上查找属性。

为了使指令与定义它的元素具有相同的作用域,请从指令定义中删除作用域对象(或使用scope: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);
    }
    }
});