AngularJS ng-options 选择选项后选择默认值导致:“TypeError:无法读取属性'[property]' of null”

Posted

技术标签:

【中文标题】AngularJS ng-options 选择选项后选择默认值导致:“TypeError:无法读取属性\'[property]\' of null”【英文标题】:AngularJS ng-options selecting default value after selecting option results in: "TypeError: Cannot read property '[property]' of null"AngularJS ng-options 选择选项后选择默认值导致:“TypeError:无法读取属性'[property]' of null” 【发布时间】:2016-11-25 12:39:31 【问题描述】:

我有一个使用 ng-options 和 ng-model 的选择标签。当我选择一个选项,然后再次选择默认选项,然后提交表单时,所选值似乎消失了。这是一个可选的选择字段,所以我需要能够检查提交时是否未选择任何内容。

我发现了几个类似的问题,但没有一个与这个确切的问题有关:

https://github.com/angular/angular.js/issues/11685(我没有自定义选择标签指令) AngularJS ng-options removed default blank value after selecting an option(我已经在使用答案中的格式了) Angularjs - TypeError: Cannot read property 'name' of undefined" when work with dropdown(我已经在使用答案中建议的模型属性) Cannot read property $scope.dropdownfield of null in angularjs(我事先声明了我的数据)

这是我制作的一个简单的小提琴来说明我的问题: https://jsfiddle.net/tjadenad/tse4ans1/29/

复制错误说明:

    在浏览器中打开控制台 从选择列表中选择一个选项。 从选择列表中选择默认(“选择一个选项”)选项。 按下提交按钮并在控制台中查看错误

这里是html

<div ng-app="app">
  <div ng-controller="TestController as ctrl">
        <form data-ng-submit="ctrl.submit()">

                <label for="test-select">
                    Label
                </label>
                <br />
                <select id="test-select" name="optionId"
                        data-ng-model="ctrl.modelObject.selectedOption" 
                        data-ng-options="option as option.description for option in ctrl.options track by option.id">
                    <option value="">Select an Option</option>
                </select>
        <br />
        <button type="submit">Submit</button>
    </form>
  </div>
</div>

这里是控制器:

angular.module('app', []).controller('TestController', function() 
    var vm = this;
    vm.modelObject =  selectedOption: id: '', description: '' ;
  vm.submit = submit;

  vm.options = [
    
            id : 1,
      description: 'Option 1'
    ,
    
        id : 2,
      description: 'Option 2'
    
  ];

  function submit() 
    var objectFromOptions = 
      optionId : vm.modelObject.selectedOption.id
    ;
  

);

我需要在提交后创建一个对象,并将选项的 id 作为属性之一。如果 id 为 null 或为空,那很好,但我找不到检查它是否为 null 的方法。我试过使用

angular.isDefined(vm.modelObject.selectedOption.id)

但在尝试访问“id”时会引发相同的错误。

我也试过了

vm.modelObject.selectedOption.hasOwnProperty('id')

像这样设置新对象的属性:

 function submit() 
    var objectFromOptions =  ;

    if (vm.modelObject.hasOwnProperty('selectedOption')) 
        console.log('selectedOption exists');
     else 
        console.log('selectedOption does not exist');
    

    if (vm.modelObject.selectedOption.hasOwnProperty('id')) 
      console.log('id exists');
      objectFromOptions.optionId = vm.modelObject.selectedOption.id
     else 
      console.log('id does not exist');
    
  

这会导致:

selectedOption exists

后面跟着错误:

TypeError: Cannot read property 'hasOwnProperty' of null

如果需要更多信息,请告诉我。提前感谢您的帮助!

【问题讨论】:

您的&lt;option value=""&gt;Select an Option&lt;/option&gt;ng-model 设置为"",而不是开始时的modelObject vm.modelObject.hasOwnProperty('selectedOption') === true,但它的值 === null。只需将“选择一个选项”添加为 vm.options 的第 0 个元素,而不是将 vm.modelObject.selectedOption = vm.options[0] 设置为默认值。 如果您为下拉菜单创建一个ng-change 处理程序,并在其中注销vm.modelObject,您将看到vm.modelObject.selectedOption === null jsfiddle.net/wyj7xswr - 固定版本 @Nosyara 不幸的是,在现实世界的例子中,这是不希望的,因为数据是从数据库中收集的。 【参考方案1】:

vm.modelObject.selectedOption 将通过 isDefined 检查——因为它已定义,但没有赋值。此外,当页面新鲜时, .id 属性也将通过 isDefined 检查。 angular.isObject() 函数在这里很有用。或者您可以只查看对象/属性并查看它们是否为 null 或计算结果为 false。

   if (angular.isObject(vm.modelObject.selectedOption) && angular.isNumber(vm.modelObject.selectedOption.id)) 
      console.log('id exists');
      objectFromOptions.optionId = vm.modelObject.selectedOption.id
     else 
      console.log('id does not exist');
    

这里有一些控制台日志:https://jsfiddle.net/f3jym9zg/

下面是一些查看变量以确定它们是否存在的示例。 var.property 也是如此。

var oops=null;//assign a value of null to the variable oops
console.log(Boolean(oops));//false
console.log(oops!=null);//false
console.log(oops==undefined);//true (== has type conversion baked in)
console.log(oops===undefined);//false (=== does not type conversion, and the types must be the same to be equal. typeOf(undefined)!==typeOf(null))
console.log(angular.isDefined(oops));//true (defined, but assigned a value of null)
console.log(angular.isDefined(oopsy));//false

if (oops) //evaluates to falsey
//never hit
 else 
//will be hit

【讨论】:

这回答了这个问题,因为最终问题是 selectedOption 为空。但是,你的小提琴和我的一样。 @Jadenity 我不经常使用 jsFiddle,很可能我没有正确分叉/保存它。

以上是关于AngularJS ng-options 选择选项后选择默认值导致:“TypeError:无法读取属性'[property]' of null”的主要内容,如果未能解决你的问题,请参考以下文章

等待为 angularjs 中的选择生成新选项

基于下拉列表中选项的选择动态更新表格的Angularjs代码

angularjs - 使用 JS 对象设置选择元素选项值

如何在 AngularJS 2 中放置已选择的选项?

仅当在 angularjs 中选择选项卡时如何调用函数(或指令)?

Angularjs:使用ng-option时如何在选择中包含空选项