在AngularJS控制器和指令之间的共享范围(Sharing scope between cont

2019-07-23 03:15发布

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

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

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

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


点击这里提琴


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>

Answer 1:

有在您的演示工作若干问题的范围。 首先,内dateChange回调,即使函数本身在控制器内声明的背景下, this回调中的引导因素,因为它是一个引导处理程序中。

每当你从第三方代码内改变角度的范围值,角度需要通过了解它$apply 。 一般最好保持该指令中的所有的第三方范围。

更角apprroach是使用ng-model上的输入端。 然后使用$.watch更改到模型。 这有助于保持所有的代码的角度范围内的控制器内。 在任何角度的应用不使用稀有ng-model上的任何形式的控制

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

在指令:

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

然后,在控制器:

$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);
        }        
});

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

编辑一个应该改变更多的产品去除var dateInput = angular.element('.datepicker')如果你想在页面中使用这个指令多于一个的元素。 它是多余的指令被用在element是在一个参数link回调已经,并且是特定于实例。 更换dateInputelement



Answer 2:

绑定到输入的CHANGEDATE事件似乎被设置为触发角框架之外。 要显示段落,叫$scope.$apply()设置后dateChanged为true。 要隐藏的延迟之后的段落,您可以使用$apply()再次传递给函数内部setTimeout ,但你可能会继续进行进一步的麻烦采用了棱角分明的$timeout()来代替。

小提琴



文章来源: Sharing scope between controller & directive in AngularJS