【问题标题】:Getting $watch is not a function error in AngularJS获取 $watch 不是 AngularJS 中的函数错误
【发布时间】:2015-11-18 23:43:10
【问题描述】:

我正在尝试在 START-DATE 大于 END-DATE 时自动更新我的 ui bootstrap datepicker 的 END-DATE。日期选择器位于模态框内,功能在 AngularJS 中完成。

我看到的所有示例都使用 $watch 和 $scope(即 $scope.$watch),但我的代码没有 $scope,不确定在我的情况下的语法是什么。

我收到:Error: vm.event.$watch is not a function

Html(在 END-DATE 将最小日期设置为“vm.event.startsAt”

      <div class="row">

                <div class="col-md-6">
                START DATE:<br />
                <p class="input-group" style="max-width: 250px">
                <input type="text" class="form-control" readonly datepicker-popup="medium" ng-model="vm.event.startsAt" is-open="vm.event.startOpen" close-text="Close" />
                <span class="input-group-btn">
                <button type="button" class="btn btn-default" ng-click="vm.toggle($event, 'startOpen', vm.event)"><i class="glyphicon glyphicon-calendar"></i></button>
                </span>
                </p>
                <timepicker ng-model="vm.event.startsAt" hour-step="1" minute-step="15" show-meridian="true"></timepicker>
                </div>

                <div class="col-md-6">
                END DATE:<br />
                <p class="input-group" style="max-width: 250px">
                <input type="text" class="form-control" readonly datepicker-popup="medium" ng-model="vm.event.endsAt" min-date="vm.event.startsAt" is-open="vm.event.endOpen" close-text="Close" />
                <span class="input-group-btn">
                <button type="button" class="btn btn-default" ng-click="vm.toggle($event, 'endOpen', vm.event)"><i class="glyphicon glyphicon-calendar"></i></button>
                </span>
                </p>
                <timepicker ng-model="vm.event.endsAt" hour-step="1" minute-step="15" show-meridian="true"></timepicker>
                </div>
      </div>     

AngularJS

'use strict';

angular
  .module('demo', ['mwl.calendar', 'ui.bootstrap', 'ngTouch', 'ngAnimate', 'ui.bootstrap.demo'])

  .controller('MainCtrl', function ($modal, moment, $http, $location) {

/* 
******************************************
****  Show Event Modal
******************************************
*/
    function showEventModal(action, event, events) {

      var modalInstance;

        modalInstance = $modal.open({
        templateUrl: 'modalEventContent.html',
        controller: function() {
          var vm = this;
          vm.action = action;
          vm.event = event;

          vm.events = events;

          vm.toggle = function($event, field, event) {
                $event.preventDefault();
                $event.stopPropagation();
                vm.event[field] = !vm.event[field];
          };

          // ----------------------------             
          // ------  Problem HERE -------
          // ----------------------------                         
          // ------  Update END DATE based on the START DATE 
          vm.event.$watch('startsAt', function (newVal, oldVal) {
            if(!newVal) return;

            // if the new start date is greater than the current end date .. update the end date
            if(vm.event.endsAt){
              if( +vm.event.endsAt < +vm.event.startsAt ){
                vm.event.endsAt = newVal;
              }
            } else {
              // just set the end date
              vm.event.endsAt = newVal;
            }
          });   


          vm.eventSaved = function(event) { 

               $http.put(urlapievents + event.eventid, vm.event).success(function(eventsuccess){
               }).error(function(err){
                    /* do something with errors */
               });

               modalInstance.close();
          };

          modalInstance.close();
          };

        },
        controllerAs: 'vm'
      });
    }

更新#1

在我的控制器中添加了 $scope 依赖,错误消失了,但函数对更改没有反应

      // ------  Update END DATE based on the START DATE (only valid for calendar view)
      $scope.$watch('vm.event.startsAt', function (newVal, oldVal) {
        if(!newVal) return;

        // if the new start date is greater than the current end date .. update the end date
        if(vm.event.endsAt){
          if( +vm.event.endsAt < +vm.event.startsAt ){
            vm.event.endsAt = newVal;
          }
        } else {
          // just set the end date
          vm.event.endsAt = newVal;
        }
      });   

【问题讨论】:

    标签: javascript angularjs


    【解决方案1】:

    $scope 依赖添加到您的控制器:

    .controller('MainCtrl', function ($scope, $modal, moment, $http, $location) { ..}
    

    这就是找不到$watch 的原因,因为它属于一个不存在的作用域 对象。

    【讨论】:

    • 感谢@bosch,我将 $scope 依赖项添加到我的控制器中,错误消失了,但该函数似乎对日期更改没有反应。任何想法?我在我的问题中添加了更新
    • 尝试用自上而下的方法观察观察者所看到的确切内容,例如$scope.$watch('vm', function(){});,然后向下钻取对象层次结构。我无法预测您应该看到什么,因为我并不真正了解您的设置(模态、控制器、指令等)。让我们更新...
    【解决方案2】:

    所以你在这里遇到问题的原因是因为 $watch 只存在于 $scope 对象上。因为您使用的是bindToController 语法,所以您没有使用范围,因此它不存在。

    如果您想在控制器中使用$watch(不建议这样做),您可以通过使用依赖注入注入 $scope 来实现。然后你可以附加$watch$scope.$watch

    如果你想使用$watch,最好在指令中使用。整体测试可能很困难。

    有一些时间选择器,如 ui-bootstraps uib-timepicker,支持 ng-change 指令进行事件处理。

    因此,如果您的 &lt;timepicker&gt;&lt;/timepicker&gt; 元素可以使用 ng-change,您可以将其添加到您的元素上,然后调用您在控制器中使用的相同验证函数。

    Here is a plunker using the ng-change of a timepicker

    【讨论】:

    • 谢谢,当 START_DATE 大于 END-DATE 时,您是否有更好的解决方案(比使用 $watch)自动更新我的 END-DATE?
    • 这个&lt;timepicker&gt; 元素是自定义输入还是引导库的一部分?
    • 我正在使用时间选择器,但日期选择器是我的问题
    猜你喜欢
    • 1970-01-01
    • 2013-10-13
    • 2015-08-07
    • 1970-01-01
    • 1970-01-01
    • 2017-12-03
    • 1970-01-01
    • 2020-10-18
    • 2020-10-25
    相关资源
    最近更新 更多