In AngularJS's ngShow or ngHide, or conditional, what happens when a property doesn't exist? (such as for a.b.c.d or !a.b.c.d)

冷暖自知 提交于 2019-12-10 11:07:00

问题


Let's say in the condition of AngularJS's ngShow, what if a property doesn't exist?

For example, if vm.foo is 1, then what if in the HTML, there is a

<div ng-show="myCtrl.foo.bar.wa.la">
    hello
</div>

and what if it is

<div ng-show="!myCtrl.foo.bar.wa.la">
    hello
</div>

Example at: https://jsfiddle.net/4yg2ocy6/1/

(If it is pure JavaScript, it will raise an exception)

I suspect that

myCtrl.foo.bar.wa.la

is treated by AngularJS as the same as:

(myCtrl.foo && myCtrl.foo.bar && myCtrl.foo.bar.wa && myCtrl.foo.bar.wa.la)

and

!myCtrl.foo.bar.wa.la

is the same as

!(myCtrl.foo && myCtrl.foo.bar && myCtrl.foo.bar.wa && myCtrl.foo.bar.wa.la)

but I can't find any documentation about it.

Another possibility is that it treats (myCtrl.foo.bar.wa.la) as one unit, if Angular can evaluate it, then return the result, but if it raises an exception, catch it and return false. So for !myCtrl.foo.bar.wa.la, it will treat it as !false and therefore is true.

Is there a more definite spec for this?


回答1:


The short (and sweet) answer

myCtrl.foo.bar.wa.la will evaluate to undefined which doesn't trigger ngShow.

The long answer

One important thing to note from Angular Expressions vs. JavaScript Expressions:

Forgiving: In JavaScript, trying to evaluate undefined properties generates ReferenceError or TypeError. In Angular, expression evaluation is forgiving to undefined and null.

This means that something like a.very.long.reference.which.does.not.exist won't throw an error and will evaluate to undefined. See this example:

angular
  .module('myApp', [])
  .controller('MainCtrl', function() {
    var vm = this;

    vm.typeOf = function(value) {
      return typeof value;
    };
  });
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.3/angular.min.js"></script>

<div ng-app="myApp">
  <div ng-controller="MainCtrl as vm">
    <div>{{ vm.typeOf(a.very.long.reference.which.does.not.exist) }}</div>
  </div>
</div>

Now, to answer your questions. Internally, both ngHide and ngShow, use a basic check to see if the expression is true or not. They do something like: if (expression) { // do this } else { // do that }.

Since both ngHide and ngShow are triggered when the expression is truthy, and that a.very.long.reference.which.does.not.exist evaluates to undefined, is clear to see why they aren't triggered when a property doesn't exist.

Some expressions and their evaluation:

undefined ? 'truthy' : 'falsy' // 'falsy'
null ? 'truthy' : 'falsy' // 'falsy'

// Booleans
true ? 'truthy' : 'falsy' // 'truthy'
false ? 'truthy' : 'falsy' // 'falsy'

// Numbers
1 ? 'truthy' : 'falsy' // 'truthy'
0 ? 'truthy' : 'falsy' // 'falsy'
0.00001 ? 'truthy' : 'falsy' // 'truthy'
NaN ? 'truthy' : 'falsy' // 'falsy'

// Strings
'something' ? 'truthy' : 'falsy' // 'truthy'
'0' ? 'truthy' : 'falsy' // 'truthy'
'' ? 'truthy' : 'falsy' // 'falsy'

({}) ? 'truthy' : 'falsy' // 'truthy'
[] ? 'truthy' : 'falsy' // 'truthy'
(new Date()) ? 'truthy' : 'falsy' // 'truthy'


来源:https://stackoverflow.com/questions/35918996/in-angularjss-ngshow-or-nghide-or-conditional-what-happens-when-a-property-do

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!