ng-include 中的指令 [英] Directives inside ng-include

查看:24
本文介绍了ng-include 中的指令的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在构建一个简单的 angularjs 应用程序,并且我正在尝试在不刷新页面的情况下实现登录.

我在做什么

在初始化时,ng-include 加载/set/save./set/save 中包含 登录 Facebook.所以当点击指令打开一个窗口时,当窗口关闭时它应该改变 ng-include 的 src.

问题

当指令在 ng-include 中使用时(ng-include src 在 init 上有默认值),什么都没有发生(控制台中没有错误,只是什么都没有),但是当我把指令放在 ng-include 之外时,它就可以工作了很好(见下面的 HTML 代码)

HTML:

…………<div id="saveModal" class="reveal-modal" data-reveal><a href fblogin>testCase</a>//^这是有效的//但如果指令在 ng-include 中,则它不起作用<ng-include src="saveTemplate"></ng-include><a class="close-reveal-modal">&#215;</a>

指令:

App.directive('fblogin', function() {返回 {转置:假,链接:函数(范围,元素,属性){element.click(函数(){var win = window.open("/auth/facebook", 'popUpWindow', 'centerscreen=true');var intervalID = setInterval(function() {如果(获胜.关闭){scope.saveTemplate = '/set/continue';范围.$应用();清除间隔(间隔ID);}}, 100);});}};});

控制器:

App.controller("SetCtrl", ["$scope", "SetHolder",函数($scope,SetHolder){$scope.saveTemplate = '/set/save';$scope.test = "加载";}]);

和/set/save

您需要登录才能保存设置.<br/><a fblogin>使用 Facebook 登录</a>

解决方案

Here is a working plunker: http://plnkr.co/edit/ilVbkHVTQWBHAs5249BT?p=preview

你被示波器上的原始值咬了.

  • 当您将 fblogin 放在 ngInclude 之外时,它位于控制器的同一范围内.
  • ngInclude 总是会创建一个新的子作用域,因此其中的任何指令都位于 子作用域 上.

来自了解范围维基:

<块引用>

作用域继承通常很简单,你通常甚至不需要知道它正在发生......直到你尝试将 2 路数据绑定(即表单元素,ng-model)绑定到一个基元(例如,数字, string, boolean) 从子作用域内部定义在父作用域上.

它不像大多数人期望的那样工作.发生的情况是子作用域获得自己的属性,隐藏/隐藏同名的父属性.这不是 AngularJS 正在做的事情——这就是 JavaScript 原型继承的工作方式.

新的 AngularJS 开发者通常没有意识到 ng-repeat、ng-switch、ng-view 和 ng-include 都会创建新的子作用域,所以当涉及到这些指令时,问题往往会出现.

遵循最佳实践"可以轻松避免原语的这个问题.总是有一个'.'在你的 ng-models 中.

在您的情况下发生的情况是 scope.saveTemplate = '/set/continue'; 只是在子作用域上创建一个变量,该变量覆盖了子作用域的 scope.saveTemplate父作用域(控制器).

I'm building a simple angularjs app and I'm trying to implement login without page refresh.

What I'm doing

On init the ng-include loads the /set/save. The /set/save got the <a fblogin>Login with Facebook</a> in it. So when clicked the directive opens a window and when the window is closed it should change the src of the ng-include.

The problem

When the directive is used inside the ng-include ( ng-include src has default value on init ), nothing happens ( no errors in console, just nothing ), but when I put the directive outside the ng-include it's working fine ( see HTML code below )

HTML:

<div id="set-creator" ng-controller="SetCtrl">
    ........
    <div id="saveModal" class="reveal-modal" data-reveal>

        <a href fblogin>testCase</a> 

                // ^this is working
                //but if the directive is inside ng-include, it's not working

        <ng-include src="saveTemplate"></ng-include>
        <a class="close-reveal-modal">&#215;</a>
    </div>
</div>

Directive:

App.directive('fblogin', function() {
return {
    transclude: false,
    link: function(scope, element, attrs) {

        element.click(function() {
            var win = window.open("/auth/facebook", 'popUpWindow', 'centerscreen=true');
            var intervalID = setInterval(function() {
                if (win.closed) {

                    scope.saveTemplate = '/set/continue';
                    scope.$apply();


                    clearInterval(intervalID);
                }
            }, 100);
        });
    }
};
});

Controller:

App.controller("SetCtrl", ["$scope", "SetHolder",
    function($scope, SetHolder) {
        $scope.saveTemplate = '/set/save';
        $scope.test = "loaded";
    }
]);

And /set/save

You need to be logged in order to save the set.
<br />
<a fblogin>Login with Facebook</a>

解决方案

Here is a working plunker: http://plnkr.co/edit/ilVbkHVTQWBHAs5249BT?p=preview

You got bitten by using a primitive value on the scope.

  • When you put fblogin outside of ngInclude it's on the same scope of the controller.
  • ngInclude always creates a new child scope so any directive inside it is on a child scope.

From Understanding Scopes wiki:

Scope inheritance is normally straightforward, and you often don't even need to know it is happening... until you try 2-way data binding (i.e., form elements, ng-model) to a primitive (e.g., number, string, boolean) defined on the parent scope from inside the child scope.

It doesn't work the way most people expect it should work. What happens is that the child scope gets its own property that hides/shadows the parent property of the same name. This is not something AngularJS is doing – this is how JavaScript prototypal inheritance works.

New AngularJS developers often do not realize that ng-repeat, ng-switch, ng-view and ng-include all create new child scopes, so the problem often shows up when these directives are involved.

This issue with primitives can be easily avoided by following the "best practice" of always have a '.' in your ng-models.

What happens in your case is that scope.saveTemplate = '/set/continue'; just create a variable on the child scope which shadows scope.saveTemplate of the parent scope (controller).

这篇关于ng-include 中的指令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆