获取$ watch不是AngularJS中的函数错误

时间:2015-11-18 14:41:26

标签: javascript angularjs

当START-DATE大于END-DATE时,我试图自动更新我的ui bootstrap日期选择器的END-DATE。日期选择器位于模态内,该函数在AngularJS中完成。

我见过的所有示例都使用带有$ scope的$ watch(即$ scope。$ watch),但是我的代码没有$ scope,不知道我的语法是什么情况下。

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

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

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

2 个答案:

答案 0 :(得分:2)

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

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

这就是$watch无法找到的原因,因为它属于范围对象,而该对象不存在。

答案 1 :(得分:0)

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

如果您想在控制器(不推荐使用)中使用$watch,可以通过注入带有依赖关系注入的$scope来实现。然后,您可以使用$watch

附加$scope.$watch

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

某些时间选择器如ui-bootstraps uib-timepicker支持事件处理的ng-change指令。

因此,如果您的<timepicker></timepicker>元素可以使用ng-change,则可以在元素上添加该元素,然后调用您在控制器中使用的相同验证函数。

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