AngularJS转移范围访问

7
我已经建立了一个通用的对话框指令,具有标题和应用/取消按钮。该对话框有一种隔离作用域。
对话框指令的内容被转移,因此其作用域是对话框作用域的同级:
来自Angular js文档:
然而,隔离作用域带来了一个新问题:如果一个转移的DOM是部件隔离作用域的子元素,那么它将无法绑定任何东西。因此,所转移的作用域是原始作用域的子级,在小部件为其本地变量创建隔离作用域之前。这使得转换和小部件隔离作用域成为兄弟关系。
但是这给我提出了一个新问题。转移的DOM应该能够响应对话框,在应用时。因此,我想在对话框上设置一个“应用”属性,并让转移的DOM观察它。然而,这是不可能的,因为他们是兄弟姐妹!
我的问题出在哪里?

我不确定你想做什么。特别是在“应该能够在应用时响应对话框”这一点上,我有些迷失了。如果应用的属性值发生变化,你希望手表做什么?你能否提供一个 fiddle 或 plunkr,展示你正在尝试做什么,并显示哪个部分不起作用? - Mark Rajcok
3个回答

13

我遇到过类似的问题,有两种方法(我所知道的)可以直接访问被转移作用域。

第一种方法是在编译函数中自己创建作用域,然后将其与克隆链接函数一起传递给转移链接函数:


function compileFn(tElement, tAttrs, transclude) {
    return linkFn;
    function linkFn(scope, element, attrs) {
        scope = scope.$new();
        scope.name = attrs.works1;
        transclude(scope, function(clone) {
            element.find('div').append(clone);
        });
    };
}

第二种方法是创建一个控制器并注入$transclude服务,该服务预绑定到新作用域。您的克隆链接函数将接收新作用域作为其第二个参数:

function Controller($element, $attrs, $transclude) {
    $transclude(function(clone, scope) {
        scope.name = $attrs.works2;
        $element.find('div').append(clone);
    });
}

在这两种情况下,您都需要提供一个克隆链接函数来执行转译而不是使用ngTransclude。

请参见http://jsfiddle.net/dbinit/wQC7G/6/ 以查看两种情况的示例。


1
对我来说,只需要使用$scope.$$nextSibling就可以找到被转译的作用域。 - Sanket Sahu

0
好的,我认为我找到了一个解决方案。 我将实际对话框包装在一个指令中,该指令定义了对话框上的作用域。 对话框的内容仍然被转换为对话框,但由于它将从对话框的父级作用域(!!)而不是对话框本身(转换工作方式如此),因此这将非常有效。
此外,我可以使用对话框上的&property使sg-import指令在应用对话框时响应。当应用对话框时,我让它在父级作用域的上下文中评估sg-apply函数(作用域自动完成,我只需从控制器的apply()函数调用该方法)。
<div sg-import>
    <div 
        sg-dialog title="Import Photographs" 
        visible="show_import_dialog" 
        sg-apply="upload()"
    >
        <div class="drop-zone">
            <div sg-photo title="{{ file.name }}">
            </div>
            <input type="file" multiple />
        </div>
    </div>
</div>

0

如果您愿意在共同祖先中创建一个模型作为带有$watch目标的交换机,那么您可以使用预先存在的设施来使每个指令突变和/或监视该交换机模型。组件的访问模式和内容控制器对于每个范围具有两个非常不同的调用签名,并且在传递的情况下存在轻微的“陷阱”。

具有双向绑定的隔离作用域

在注册指令的隔离作用域时,“=attrName”将导致检查名为“attrName”的domainName属性。Angular将设置双向绑定,以便对任一范围中的模型值进行更改也会影响兄弟范围中的模型。

示例

在controller-parent.js中:

module.controller( 'ParentController', function() {
    $scope.switchboard = { };
}

在 directive-sg-dialogue.js 中
return {
    scope: {
  isolatedPeer: "=dialogModel"
};

...在指令元数据中...

<div ng-controller="ParentController">
    <sg-dialog dialog-model="switchboard">
        <div ng-controller="ChildController"></div>
    </sg-dialog>
</div>

...在某些应用程序视图模板中,以及...

$scope.switchboard = { isApplied: false } 

...在绑定到应用程序视图模板的控制器中...

然后您就可以开始了...

$scope.$watch( 'switchboard.isApplied', function(newValue, oldValue) { })

...在共同祖先中查找,并在之后获取回调...

isolatedPeer.isApplied = true;

...在隔离作用域中。

原型继承

只要您不明确设置$ scope.swtichboard在被转换的子级中,您就可以从转换的子级中的angular表达式访问“switchboard.isApplied”,并使插值引擎“查找”父控制器在其自己的作用域中分配和存储的值。

例如,每当对话框关闭时,将调用以下回调:

$scope.$watch( 'switchboard.isApplied', function(newValue, oldValue) { } );

这是因为被转入的子元素总是被赋予基本作用域,而不是隔离作用域。

希望这对您有所帮助!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接