共享控制器与放大器之间的范围;指令在AngularJS [英] Sharing scope between controller & directive in AngularJS

查看:111
本文介绍了共享控制器与放大器之间的范围;指令在AngularJS的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一个指令来包装一个jQuery插件,我通过一个配置对象从控制器的指令插件。 (作品)

在配置对象是,我想在一个事件调用回调。 (作品)

在回调,我想修改控制器的$范围属性,它的不工作的。角不承认该属性已更改出于某种原因,这使我相信,在回调$范围比控制器的$范围不同。我的问题是我不为什么。

任何人都可以点我在正确的方向?


点击这里查看小提琴


app.js

  VAR应用= angular.module(应用,[])
    .directive(日期选择器,功能(){
        返回{
            限制:'A',
            链接:功能(范围,元素,ATTRS){
                //取消注释以下原因线
                //日期变了!文本显示,
                //我期望它。
                // scope.dateChanged = TRUE;                VAR dateInput = angular.element('。日期选择器)                dateInput.datepicker(scope.datepickerOpts);                //该日期选择器触发一个事件CHANGEDATE
                //当选择的日期。我想执行
                //在控制器中定义的回调。
                // ---
                //问题:
                //角不承认$ scope.dateChanged
                //回调而改变。该视图不会更新。
                dateInput.bind('CHANGEDATE',scope.onDateChange);
            }
        };
    });VAR MyModule的= angular.module('Mymodule中',['应用'])
    .controller('MyCtrl',['$范围',函数($范围){
        $ scope.dateChanged = FALSE;        $ scope.datepickerOpts = {
            autoclose:真实,
            格式为:MM-DD-YYYY
        };        $ scope.onDateChange =功能(){
            警报('onDateChange叫!');            // ------------------
            //问题区域:
            //这不导致日期变了!文字显示。
            // ------------------
            $ scope.dateChanged =真;            的setTimeout(函数(){
                $ scope.dateChanged = FALSE;
            },5000);
        };
    }]);

HTML

 < D​​IV NG控制器=MyCtrl>
    < p NG秀=dateChanged>更改日期<!/ P>
    <输入类型=文本值=2012年2月16日级=日期选择日期选择器=>
< / DIV>


解决方案

在您的演示工作有许多的范围的问题。首先, dateChange 回调中,即使函数本身在控制器内声明的上下文中,这个内回调是引导元件,因为它是一个自举处理程序中。

当你从第三方code内改变角度范围值,角度需要了解它使用 $适用。一般最好把所有第三方的范围内的指令

一个更加棱角分明apprroach是使用 NG-模型输入。然后使用 $。看更改到模型。这有助于保持所有code角范围内的控制器内。在任何角度的应用程序不使用 NG-模型在任何窗体控件

罕见

<输入类型=文本级=日期选择日期选择器=NG-模式=数值指明MyDate&GT ;

在指令:

dateInput.bind('CHANGEDATE',函数(){
      范围。$应用(函数(){
         范围[attrs.ngModel] = element.val()
      });
});

然后在控制器:

$范围。$腕表('数值指明MyDate',函数(OLDVAL,的newval){
       如果(OLDVAL!=的newval){
           / *因为这code为角上下文将用于隐藏/显示现在的工作* /
            $ scope.dateChanged =真;
             $超时(函数(){
                   $ scope.dateChanged = FALSE;
              },5000);
        }
});

演示: http://jsfiddle.net/qxjck/10/

修改应该改变一个多产品删除 VAR dateInput = angular.element('。日期选择器')如果你想使用这个指令页面多个元素。它是多余的指令被用在元素是在链接回调已经论据之一,是特定于实例。替换 dateInput 元素

I've created a directive to wrap a jQuery plugin, and I pass a config object for the plugin from the controller to the directive. (works)

In the config object is a callback that I want to call on an event. (works)

In the callback, I want to modify a property on the controller's $scope, which does not work. Angular does not recognize that the property has changed for some reason, which leads me to believe that the $scope in the callback is different than the controller's $scope. My problem is I just don't why.

Can anybody point me in the right direction?


Click here for Fiddle


app.js

var app = angular.module('app', [])
    .directive('datepicker', function () {
        return {
            restrict: 'A',
            link: function (scope, element, attrs) {
                // Uncommenting the line below causes
                // the "date changed!" text to appear,
                // as I expect it would.
                // scope.dateChanged = true;

                var dateInput = angular.element('.datepicker')

                dateInput.datepicker(scope.datepickerOpts);

                // The datepicker fires a changeDate event
                // when a date is chosen. I want to execute the
                // callback defined in a controller.
                // ---
                // PROBLEM: 
                // Angular does not recognize that $scope.dateChanged
                // is changed in the callback. The view does not update.
                dateInput.bind('changeDate', scope.onDateChange);
            }
        };
    });

var myModule = angular.module('myModule', ['app'])
    .controller('MyCtrl', ['$scope', function ($scope) {
        $scope.dateChanged = false;

        $scope.datepickerOpts = {
            autoclose: true,
            format: 'mm-dd-yyyy'
        };

        $scope.onDateChange = function () {
            alert('onDateChange called!');

            // ------------------
            // PROBLEM AREA:
            // This doesnt cause the "date changed!" text to show.
            // ------------------
            $scope.dateChanged = true;

            setTimeout(function () {
                $scope.dateChanged = false;
            }, 5000);
        };
    }]);

html

<div ng-controller="MyCtrl">
    <p ng-show="dateChanged">date changed!</p>
    <input type="text" value="02-16-2012" class="datepicker" datepicker="">
</div>

解决方案

There are a number of scope issues at work in your demo. First , within the dateChange callback, even though the function itself is declared inside the controller, the context of this within the callback is the bootstrap element since it is within a bootstrap handler.

Whenever you change angular scope values from within third party code , angular needs to know about it by using $apply. Generally best to keep all third party scopes inside the directive.

A more angular apprroach is to use ng-model on the input. Then use $.watch for changes to the model. This helps keep all the code inside the controller within angular context. Is rare in any angular application not to use ng-model on any form controls

 <input type="text"  class="datepicker" datepicker="" ng-model="myDate">

Within directive:

dateInput.bind('changeDate',function(){
      scope.$apply(function(){
         scope[attrs.ngModel] = element.val()
      });
});

Then in Controller:

$scope.$watch('myDate',function(oldVal,newVal){ 
       if(oldVal !=newVal){
           /* since this code is in angular context will work for the hide/show now*/
            $scope.dateChanged=true;
             $timeout(function(){
                   $scope.dateChanged=false;
              },5000);
        }        
});

Demo: http://jsfiddle.net/qxjck/10/

EDIT One more item that should change is remove var dateInput = angular.element('.datepicker') if you want to use this directive on more than one element in page. It is redundant being used in directive where element is one of the arguments in the link callback already, and is instance specific. Replace dateInput with element

这篇关于共享控制器与放大器之间的范围;指令在AngularJS的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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