本文介绍了与ngChange为&LT的问题;选择>之后1.3.0 RC0的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

限时删除!!

我一直使用的1.3测试版,现在转移到1.3.1后,我发现它通过检查所有早期版本我看到它出现在 1.3.0 RC1已经开始的一个问题。

我有code是这样的:

 <选择NG模型=home.modal.topicId
        NG-变化=ctrl.modalTopicChanged()
        NG-选项=item.id作为item.name在home.modal.option.topics.data项
        NG-所需=真>
        <选项风格=显示:无;值=>选择主题< /选项>
< /选择>

此前RC1的NG-变化的不被解雇当表单是的首先显示即可。现在,它正在与未定义 home.modal.topicId解雇。这对我来说是一个重大更改,但它不是在重大更改部分中提到,我不知道,如果是一个尚未被发现的错误。

下面是公司生产的堆栈跟踪:

 类型错误:无法读取的未定义的属性数据映射
    在AdminProblemController.modalTopicChanged(http://127.0.0.1:17315/Content/app/admin/controllers/ProblemController.js:109:114)
    在$ parseFunctionCall(http://127.0.0.1:17315/Scripts/angular.js:11387:18)
    在范围内。$ get.Scope。$的eval(http://127.0.0.1:17315/Scripts/angular.js:13276:28)
    在http://127.0.0.1:17315/Scripts/angular.js:19888:13
    在http://127.0.0.1:17315/Scripts/angular.js:19499:9
    在的forEach(http://127.0.0.1:17315/Scripts/angular.js:331:20)
    在$$ writeModelToScope(http://127.0.0.1:17315/Scripts/angular.js:19497:5)
    在writeToModelIfNeeded(http://127.0.0.1:17315/Scripts/angular.js:19490:14)
    在http://127.0.0.1:17315/Scripts/angular.js:19484:9
    在validationDone(http://127.0.0.1:17315/Scripts/angular.js:19420:9)

我发现这里是一个新的功能:writeToModelIfNeeded

当我查看更改日志的差异,我找不到当我检查所有的变化和线路号引入此功能的任何提及。

我想在这得到一些建议。首先是有可能找到导致另外writeToModelIfNeeded的再其次是本作的选择框的正确功能的变化。我觉得整个的想法是,如果模型值定义NG-变化只会激发。

有关参考这里是新的code,它似乎已经加入1.3.0 RC.1面积

  **
   * @ngdoc方法
   * @name ngModel.NgModelController#$ commitViewValue
   *
   * @description
   *提交挂起的更新到`$ modelValue`。
   *
   *更新可以通过去抖事件正在申请或因为输入正在等待一些未来
   *在`NG-模型options`定义的事件。这种方法很少需要为`NgModelController`
   *通常处理响应于输入事件调用此。
   * /
  这一点。$ commitViewValue =功能(){
    VAR viewValue = $ CTRL viewValue。    $ timeout.cancel(pendingDebounce);    //如果视图值没有改变,那么我们就应该退出,除非在有这样的情形
    //元素上的本机验证器。在这种情况下,验证状态可能已经改变,即使
    //将viewValue一直保持空。
    如果(CTRL $$ lastCommittedViewValue === viewValue&放大器;&安培;!(viewValue ==''|| CTRL $$ hasNativeValidators)){
      返回;
    }
    CTRL $$ lastCommittedViewValue = viewValue。    //改变脏
    如果(CTRL $原始){
      。CTRL $脏= TRUE;
      。CTRL $质朴= FALSE;
      $ animate.removeClass($元素,PRISTINE_CLASS);
      $ animate.addClass($元素,DIRTY_CLASS);
      parentForm $使用setDirty()。
    }
    这$$ parseAndValidate()。
  };  这$$ parseAndValidate =功能(){
    VAR parserValid = TRUE,
        viewValue = CTRL $$ lastCommittedViewValue,
        modelValue = viewValue;
    对于(VAR I = 0; I< CTRL $ parsers.length;我++){
      。modelValue = $ CTRL解析器[I](modelValue);
      如果(isUndefined(modelValue)){
        parserValid = FALSE;
        打破;
      }
    }
    如果(ISNUMBER(CTRL $ modelValue)及&安培; isNaN(CTRL $ modelValue)){
      // Ctrl键。$ modelValue尚未触及尚未...
      。CTRL $ modelValue = ngModelGet();
    }
    VAR prevModelValue = $ CTRL modelValue。
    VAR allowInvalid = $ CTRL选择与放大器;&安培; CTRL $ options.allowInvalid。
    如果(allowInvalid){
      CTRL $ modelValue = modelValue。
      writeToModelIfNeeded();
    }
    Ctrl键。$$ runValidators(parserValid,modelValue,viewValue,函数(){
      如果(!allowInvalid){
        Ctrl键。$ modelValue = CTRL $有效吗? modelValue:未定义;
        writeToModelIfNeeded();
      }
    });    功能writeToModelIfNeeded(){
      如果(按Ctrl。$ modelValue!== prevModelValue){
        CTRL $$ writeModelToScope()。
      }
    }
  };  这$$ writeModelToScope =功能(){
    ngModelSet(CTRL $ modelValue);
    的forEach(Ctrl键。$ viewChangeListeners,功能(监听){
      尝试{
        听者();
      }赶上(E){
        $ exceptionHandler的(E);
      }
    });
  };


解决方案

我能够通过这样做是为了重现您的问题。没有看到你的控制器,虽然不知道,如果同样的事情:

  this.modal = {
      topicId:空,
      选项​​:{
        主题:{
          数据:[{ID:1,名称:ITEM1'},{ID:2,名称:ITEM2'}]
        }
      }
    };

这是怎么发生的是角度说null是一个无效的值,因此默认情况下它设置为未定义。你可以将其设置为未定义,或将其加入您的HTML解决这个问题:

  NG-模式选项={allowInvalid:真正}

也测试了何塞普plunker和更改值设置为null也造成ngChange火

I have been using a beta version of 1.3 and now after moving to 1.3.1 I notice a problem which by checking all earlier versions I see it appears to have started in 1.3.0 rc1.

I have code like this:

<select ng-model="home.modal.topicId"
        ng-change="ctrl.modalTopicChanged()"
        ng-options="item.id as item.name for item in home.modal.option.topics.data"
        ng-required="true">
        <option style="display: none;" value="">Select Topic</option>
</select>

Prior to rc1 the ng-change was not being fired when the form was first displayed. Now it is being fired with a home.modal.topicId of undefined. This is a breaking change for me but it's not mentioned in the breaking change section and I wonder if it's a bug that has yet to be noticed.

Here is the stack trace produced:

TypeError: Cannot read property 'dataMap' of undefined
    at AdminProblemController.modalTopicChanged (http://127.0.0.1:17315/Content/app/admin/controllers/ProblemController.js:109:114)
    at $parseFunctionCall (http://127.0.0.1:17315/Scripts/angular.js:11387:18)
    at Scope.$get.Scope.$eval (http://127.0.0.1:17315/Scripts/angular.js:13276:28)
    at http://127.0.0.1:17315/Scripts/angular.js:19888:13
    at http://127.0.0.1:17315/Scripts/angular.js:19499:9
    at forEach (http://127.0.0.1:17315/Scripts/angular.js:331:20)
    at $$writeModelToScope (http://127.0.0.1:17315/Scripts/angular.js:19497:5)
    at writeToModelIfNeeded (http://127.0.0.1:17315/Scripts/angular.js:19490:14)
    at http://127.0.0.1:17315/Scripts/angular.js:19484:9
    at validationDone (http://127.0.0.1:17315/Scripts/angular.js:19420:9)

What I notice here is a new function: writeToModelIfNeeded

When I look at the change log differences I cannot find any mention of this function being introduced when I check all the changes and the line numbers.

I would like to get some advice on this. Firstly is it possible to find the change that caused the addition of the writeToModelIfNeeded then secondly is this the correct functionality for the select box. I thought the whole idea was that the ng-change would only fire if the model value was defined.

For reference here's the area of new code that seems to have been added with 1.3.0 rc.1

**
   * @ngdoc method
   * @name ngModel.NgModelController#$commitViewValue
   *
   * @description
   * Commit a pending update to the `$modelValue`.
   *
   * Updates may be pending by a debounced event or because the input is waiting for a some future
   * event defined in `ng-model-options`. this method is rarely needed as `NgModelController`
   * usually handles calling this in response to input events.
   */
  this.$commitViewValue = function() {
    var viewValue = ctrl.$viewValue;

    $timeout.cancel(pendingDebounce);

    // If the view value has not changed then we should just exit, except in the case where there is
    // a native validator on the element. In this case the validation state may have changed even though
    // the viewValue has stayed empty.
    if (ctrl.$$lastCommittedViewValue === viewValue && (viewValue !== '' || !ctrl.$$hasNativeValidators)) {
      return;
    }
    ctrl.$$lastCommittedViewValue = viewValue;

    // change to dirty
    if (ctrl.$pristine) {
      ctrl.$dirty = true;
      ctrl.$pristine = false;
      $animate.removeClass($element, PRISTINE_CLASS);
      $animate.addClass($element, DIRTY_CLASS);
      parentForm.$setDirty();
    }
    this.$$parseAndValidate();
  };

  this.$$parseAndValidate = function() {
    var parserValid = true,
        viewValue = ctrl.$$lastCommittedViewValue,
        modelValue = viewValue;
    for(var i = 0; i < ctrl.$parsers.length; i++) {
      modelValue = ctrl.$parsers[i](modelValue);
      if (isUndefined(modelValue)) {
        parserValid = false;
        break;
      }
    }
    if (isNumber(ctrl.$modelValue) && isNaN(ctrl.$modelValue)) {
      // ctrl.$modelValue has not been touched yet...
      ctrl.$modelValue = ngModelGet();
    }
    var prevModelValue = ctrl.$modelValue;
    var allowInvalid = ctrl.$options && ctrl.$options.allowInvalid;
    if (allowInvalid) {
      ctrl.$modelValue = modelValue;
      writeToModelIfNeeded();
    }
    ctrl.$$runValidators(parserValid, modelValue, viewValue, function() {
      if (!allowInvalid) {
        ctrl.$modelValue = ctrl.$valid ? modelValue : undefined;
        writeToModelIfNeeded();
      }
    });

    function writeToModelIfNeeded() {
      if (ctrl.$modelValue !== prevModelValue) {
        ctrl.$$writeModelToScope();
      }
    }
  };

  this.$$writeModelToScope = function() {
    ngModelSet(ctrl.$modelValue);
    forEach(ctrl.$viewChangeListeners, function(listener) {
      try {
        listener();
      } catch(e) {
        $exceptionHandler(e);
      }
    });
  };
解决方案

I was able to reproduce your issue by doing this. Without seeing your controller though not sure if same thing:

 this.modal = {
      topicId:null,
      option:{
        topics:{
          data:[{id:1,name:'item1'},{id:2,name:'item2'}]
        }
      }
    };

What is happening here is that angular says null is an invalid value so by default sets it to undefined. You can fix this by setting it to 'undefined' or adding this to your html:

ng-model-options="{allowInvalid:true}"

also tested Josep plunker and changing that value to null also caused ngChange to fire

这篇关于与ngChange为&LT的问题;选择&GT;之后1.3.0 RC0的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

1403页,肝出来的..

09-06 23:54