angularjs transclusion scope access

时间:2013-01-19 14:14:58

标签: scope angularjs transclusion

我已经设置了一个带有标题和应用/取消按钮的通用对话框指令。 该对话框具有独立的范围。

对话框指令的内容被转换,因此它的范围是对话范围的兄弟:

来自Angular js docs:

  

但是,隔离范围会产生一个新问题:如果转换的DOM是小部件隔离范围的子级,则它将无法绑定到任何内容。因此,在窗口小部件为其局部变量创建隔离范围之前,转换范围是原始范围的子级。这使得transcluded和widget隔离范围的兄弟姐妹。

这给我带来了一个新问题。转换后的DOM应该能够在应用时响应对话框。因此,我想在对话框上设置一个“应用”属性,让被抄袭的DOM观看它。但这是不可能的,因为他们是兄弟姐妹!

我哪里错了?

3 个答案:

答案 0 :(得分:13)

我遇到了类似的事情,有两种方式(我知道)可以直接访问被转换的范围。

第一种是在编译函数中自己创建作用域,然后将它与一个克隆链接函数一起传递给transclude链接函数:

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 :(得分:0)

哦,我想我找到了解决方案。 我已经将实际对话框包装在一个指令中,该指令定义了对话框的范围。 对话框的内容仍然在对话框中被转换,但由于它将从parent of the dialog(!!)获取它的父作用域,而不是对话框本身(转换以这种方式工作),这将非常有效。< / p>

此外,在对话框中使用&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>

答案 2 :(得分: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,就可以从已转换子级中的角度表达式访问“switchboard.isApplied”,并让插值引擎“找到”值为“已分配”的值由父控制器存储在自己的范围内。

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

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

这是有效的,因为被饶恕的孩子总是被赋予基本范围,而不是孤立的范围。

希望这有用!