Why do certain html elements need Angular.JS direc

2019-06-24 01:40发布

I've been working through the Angular.JS tutorial, and I'm on step 6. The tutorial shows the following code snippet:

<ul class="phones">
  <li ng-repeat="phone in phones | filter:query | orderBy:orderProp" class="thumbnail">
    <a href="#/phones/{{phone.id}}" class="thumb"><img ng-src="{{phone.imageUrl}}"></a>
    <a href="#/phones/{{phone.id}}">{{phone.name}}</a>
    <p>{{phone.snippet}}</p>
  </li>
</ul>

It then goes on to explain:

We also added ... the ngSrc directive. That directive prevents the browser from treating the angular {{ expression }} markup literally, and initiating a request to invalid url /app/{{phone.imageUrl}}, which it would have done if we had only specified an attribute binding in a regular src attribute (). Using the ngSrc directive prevents the browser from making an http request to an invalid location.

So, what it's saying is, the img element needs to use the special Angular.JS directive ngSrc so it can correctly parse the double curly braces. But they fail to explain why the a element doesn't require the same special directive.

<a href="#/phones/{{phone.id}}">

What's going on here? href can correctly parse the double curly braces, but src can't? Why?

2条回答
【Aperson】
2楼-- · 2019-06-24 02:00

To add to David's great answer, the basic difference is that the href doesn't trigger any server calls on page load (because there is no reason to, it's triggered only when you follow the link), while, on the other hand, all image tags are loaded when the page loads, and of course, the server tries to fetch them right away as their path is found in the src attribute.

The problem is that the DOM is loaded much before angular is (because DOM initiates angular), so there is no parsing/interpolation taking place before the angular loads, but all the image tags are ready and system is starting to fetch them. At that point, the source for your image is {{phone.imageUrl}} and it will try to fetch that first, returning errors.

ng-src avoids this default behaviour, and adds the src to the image once the angular is ready.

查看更多
贼婆χ
3楼-- · 2019-06-24 02:11

The AngularJS docs are great place to find this type of information.

http://docs.angularjs.org/api/ng/directive/ngSrc

Using Angular markup like {{hash}} in a src attribute doesn't work right: The browser will fetch from the URL with the literal text {{hash}} until Angular replaces the expression inside {{hash}}. The ngSrc directive solves this problem.

There is actually a ng-href directive:

http://docs.angularjs.org/api/ng/directive/ngHref

Using Angular markup like {{hash}} in an href attribute will make the link go to the wrong URL if the user clicks it before Angular has a chance to replace the {{hash}} markup with its value. Until Angular replaces the markup the link will be broken and will most likely return a 404 error.

So essentially what this all means is that if you write a url like this:

<a href="#/phones/{{ phone.id }}">

However, the hashes inside the URL can be an issue if Angular hasn't loaded yet. If the user attempts to click that link before Angular binds the link will literally be the {{ phone.id }} rather than the actual bound value.

How often, does this happen? Well it depends on how long it takes your page to load. If you're resolving a promise onto the page without resolving the route then the user will definitely have a chance to click the improper link.

Long story short, different directives, same reasoning.

查看更多
登录 后发表回答