Heim  >  Fragen und Antworten  >  Hauptteil

angular.js - angularjs scope.$watch取不到input变化的值

我想用angularjs和my97datepicker做一个东西,写了一个direcitve,在点击选择完时间之后,把值同步到scope上面。描述的有点乱,看下主要代码:

javascriptvar datepicker=angular.module("datepicker",[]);
datepicker.controller("datepickerCtrl",function($scope){
    $scope.date="2014-10-14";
});
datepicker.directive("datePicker",function(){
    return {
        restrict:"A",
        link:function(scope,element,attr){
            element.bind("click",function(){
                window.WdatePicker();
            });
            //问题在这里,无法取到变化的值,而且加上这个,连初始的值都无法显示出来。
            scope.$watch(attr.value,function(newVal){
                scope.date=newVal;
            });
        }
    };
});

在线地址:http://jsfiddle.sinaapp.com/4zz6nvadg/embedded。初学angularjs,每次写directive都是卡在$watch这里。

仅有的幸福仅有的幸福2737 Tage vor839

Antworte allen(5)Ich werde antworten

  • PHP中文网

    PHP中文网2017-05-15 16:51:37

    我不知道怎么解决,因为你用的那个插件我没有用过,现在也没时间去研究它。不过我可以告诉你问题出在哪里,你试着自己找找解决方案吧。先看截图:

    1. 先注释了 $watch 相关的代码,以确保插件正确执行
    2. 注意下面:2014-10-14 出现在 DOM 的哪里了吗?
    3. $watch 部分你监视的是 attr.value,然而根据截图可以发现插件设定的日期根本就不是保存在 input[value] 这里,无论如何 input[value] 都是空值
    4. 因此,$watch 所做的仅仅是读取一个不存在的值,并且覆盖了 model,这就是为什么加上 $watch 部分之后,连 model 都失效的缘故。

    知道原因之后,解决办法就简单了,要么让插件把你想要的值写到 input[value] 去,要么反过来,找到正确的地方去取值去 $watch,具体办法自己去查询插件的文档或源码吧。


    吃了晚饭,帮你看一下插件的源代码,实际上人家提供了几个事件回调函数,而且你不必非用 $watch 的,代码如下:

    var datepicker=angular.module("datepicker",[]);
    datepicker.controller("datepickerCtrl",function($scope){
      $scope.date="2014-10-14";
    });
    datepicker.directive("datePicker",function(){
      return {
        restrict:"A",
        link:function(scope, element, attr){
          element.bind("click", function () {
            window.WdatePicker({
              onpicked: function () {
                scope.$apply(scope.date = this.value);
              }
            });
          });
        }
      };
    });
    

    Demo: http://jsfiddle.sinaapp.com/4zz6n9usy

    想用 $watch 也可以,这样写:

    var datepicker=angular.module("datepicker",[]);
    datepicker.controller("datepickerCtrl",function($scope){
      $scope.date="2014-10-14";
    });
    datepicker.directive("datePicker",function(){
      return {
        restrict:"A",
        link:function(scope, element, attr){
          element.bind("click", function () {
            window.WdatePicker({
              onpicked: function () { scope.$digest(); }
            });
          });
          scope.$watch(
            function () { return element[0].value },
            function (newValue) { scope.date = newValue; }
          );
        }
      };
    });
    

    Demo: http://jsfiddle.sinaapp.com/4zz6n9t9q

    注意,这里第一个参数不能是直接 element[0].value,因为这个值是一个 primitive string,而不是 angular 封装过的对象,所以要用一个 getter 函数显式的去获取,否则你拿不到的。

    而且这里还必须得依赖插件的回调函数做一下 scope.$digest(),否则 scope.date 不会自动更新。由此可见,还是第一个例子更简单,性能也更好。

    Antwort
    0
  • PHPz

    PHPz2017-05-15 16:51:37

    不知道为何要这么用,这里你需要明确一个概念,属性和 scope 是不同的,如果要绑定属性值到 scope 中,需要在 directive 中去做 scope 的声明,有以下三种方式:

    • =attr 双向
    • @attr 单向
    • &attr 函数

    按照你的思路,可能是下面的方式:

    scope: {
      value: '=value'
    }
    

    但即使是做了绑定,还要明白这个元素的 value 的值变更并不是 Angular 默认会做监控的,这个绑定只是说要去绑定这个属性值对应的变量,当然无法 watch 到 value 的变更。
    其实用 ng-model 和 ng-change 足够了。

    最终可能是这样:

    <input ng-model="date" date-picker />
    

    Antwort
    0
  • 黄舟

    黄舟2017-05-15 16:51:37

    试试把$scope传进来!$watch是在$scope基础上的

    Antwort
    0
  • 習慣沉默

    習慣沉默2017-05-15 16:51:37

    没找到link的详细文档,不能确定attr的具体使用方法,不过觉得你可以试试$watch一下element的value。

    至于楼上2位,在directive里scope就是它的$scope,attr是link里的一个参数,不需要另外定义。

    Antwort
    0
  • 某草草

    某草草2017-05-15 16:51:37

    楼主你好,请问这个问题最后如何解决,我现在是ng-model取到的值还是undefined

    Antwort
    0
  • StornierenAntwort