使用 ng-model 时 AngularJS $scope 不更新(ng-change 触发?)

Posted

技术标签:

【中文标题】使用 ng-model 时 AngularJS $scope 不更新(ng-change 触发?)【英文标题】:AngularJS $scope not updating when using ng-model (ng-change fires?) 【发布时间】:2015-03-08 00:52:13 【问题描述】:

我是 Angular(和 javascript)的新手,所以这可能是一个非常简单的原因,它不起作用。我有一个日期选择器,它给我一个日期,我根据该日期生成一些要显示的内容。因此,如果日期选择器中的日期发生变化,我需要重新生成内容。我可以做到(ng-change 正在执行)---问题是我得到了相同的内容,因为日期实际上并没有改变。我可以通过警报来确认它以显示生成内容时使用的日期。日期最初设置为默认值(昨天的日期),因此第一次生成内容时,它工作正常,但是当我尝试使用日期选择器更改日期时,它不会改变。

html 代码:

<p class="col-xs-2 col-md-2 col-md-offset-5 text-center input-group">
    <span class="form-control input-sm" style="cursor:pointer" ng-click="openDatePicker($event, 'openedDaily')"> 
        ds_date | date:'MM/dd/yyyy'
    </span>
    <input type="hidden" class="form-control input-sm"
        ng-model="ds_date" ng-change="regenerate();"
        ng-required="true"
        format-day-title="MM/dd/yyyy"
        datepicker-popup="MM/dd/yyyy"
        show-button-bar="false"
        is-open="openedDaily"
        min-date="onemonthago"
        max-date="yesterday"
        close-text="Close" />
    <span class="input-group-btn">
        <button type="button" class="btn btn-sm btn-default" ng-click="openDatePicker($event, 'openedDaily')"><i class="glyphicon glyphicon-calendar"></i></button>
    </span>
</p> 

控制器:

angular.module('twApp')
.controller('ReportsCtrl', function ($scope, $modal, $filter, LoginData, $timeout, $http) 
    $scope.yesterday = new Date();
    $scope.yesterday.setDate($scope.yesterday.getDate() - 1);
    $scope.reportOutput = null;
    $scope.ds_date= $scope.yesterday;


    $scope.openDatePicker = function($event, name) 
        $event.preventDefault();
        $event.stopPropagation();
        $scope[name] = true;
  alert($scope.ds_date);
    ;


    function dateString(input) 
        return $filter('date')(input, 'yyyy-MM-dd');
    

    $scope.goBack = function()
  $scope.reportOutput = null;
    ;

    $scope.regenerate = function()
  $scope.generate($scope.which);
    ;

    $scope.generate = function(id) 
        var promise = requestReport(id);
        if (promise !== null) 
    alert('generated!!   '+$scope.ds_date);
            $scope.loading = true;
            promise.then(
                function() 
                    $scope.loading = false;
                , function() 
                    alert('There was a problem generating the report.  Please try again.');
                    $scope.loading = false;
                
            );
        
    ;

    var requestReport = function(id) 
         //do stuff
    ;
);

编辑:这是生成日期选择器的内容:

<script id="template/datepicker/datepicker.html" type="text/ng-template">
        <div role="application" ng-keydown="keydown($event)">
          <daypicker tabindex="0"></daypicker>
        </div>
    </script>
    <script id="template/datepicker/popup.html" type="text/ng-template">
        <ul class="dropdown-menu" ng-style="display: (isOpen && 'block') || 'none', top: position.top+'px', left: position.left+'px'" ng-keydown="keydown($event)">
            <li ng-transclude></li>
            <li ng-if="showButtonBar" style="padding:10px 9px 2px">
                <span class="btn-group">
                    <button type="button" class="btn btn-sm btn-info" ng-click="select('today')"> getText('current') </button>
                    <button type="button" class="btn btn-sm btn-danger" ng-click="select(null)"> getText('clear') </button>
                </span>
                <button type="button" class="btn btn-sm btn-success pull-right" ng-click="close()"> getText('close') </button>
            </li>
        </ul>
    </script>
    <script id="template/datepicker/day.html" type="text/ng-template">
        <table class="datepickertable">
          <thead>
            <tr>
              <th><button type="button" class="btn btn-default btn-sm pull-left" ng-click="move(-1)" tabindex="-1"><i class="glyphicon glyphicon-chevron-left"></i></button></th>
              <th colspan="5" class="text-center"><strong>title</strong></th>
              <th><button type="button" class="btn btn-default btn-sm pull-right" ng-click="move(1)" tabindex="-1"><i class="glyphicon glyphicon-chevron-right"></i></button></th>
            </tr>
            <tr>
              <th ng-repeat="label in labels track by $index" class="text-center"><small aria-label="label.full">label.abbr</small></th>
            </tr>
          </thead>
          <tbody>
            <tr ng-repeat="row in rows track by $index">
              <td ng-repeat="dt in row track by dt.date" class="text-center" role="gridcell" id="dt.uid" aria-disabled="!!dt.disabled">
                <button type="button" style="width:100%;" class="btn btn-default btn-sm" ng-class="'btn-info': dt.selected, active: isActive(dt)" ng-click="select(dt.date)" ng-disabled="dt.disabled" tabindex="-1"><span ng-class="'text-muted': dt.secondary, 'text-info': dt.current">dt.label</span></button>
              </td>
            </tr>
          </tbody>
        </table>
    </script>

【问题讨论】:

究竟是什么生成了 datePicker? @itamar 模板已添加到问题中。 @senschen 每天打开什么?你认为它是 dateValue 吗? @pankajparkar 我想(这不是我写的代码,所以我不确定它在做什么——发生了很多事情,这就是我为什么有这么多麻烦)openedDaily 是一个布尔值,用于在日期选择器上设置样式。 @pankajparkar Iguess 我不明白日期是如何(应该是)从日期选择器中设置的,因为我假设 $scope.openDatePicker 已经处理好了。但是当它停止工作并开始寻找问题时,我仔细查看了那里的代码,现在我不确定它是如何工作的。但就像我说的,我是 angularjs 的新手,所以这里有很多我不完全理解的东西。 【参考方案1】:

您需要在 daypicker 包装器中放入某种 ng-model 以将值传递回范围。尝试添加 ng-model="ds_date"

【讨论】:

你会建议把它放在包装的什么地方? @senschen

以上是关于使用 ng-model 时 AngularJS $scope 不更新(ng-change 触发?)的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 AngularJS 的 ng-model 创建一个数组以及如何使用 jquery 提交?

AngularJS - 选择的 ng-model 工作不正常

如何在angularjs中的选择框或内部选项中使用ng-model?

ng-model 绑定到 ng-repeat Angularjs 中的元素

AngularJS - 创建一个使用 ng-model 的指令

外部 SVG 文档可以包含 AngularJS ng-click 或 ng-model 指令吗?