AngularJS MTV Meetup: Best Practices (2012/12/11)

By: Angular

1690   16   350132

Uploaded on 12/12/2012

http://www.meetup.com/AngularJS-MTV/events/93943412/
Presentation slides available at: http://goo.gl/CD0Is
Live from the Mountain View, CA meetup, Miško Hevery discusses the advantages and disadvantages of various design choices when structuring an app in AngularJS, and some of the best practices that we use in our own development.

Some of the topics we'll cover:
- Style best practices that we use in our own projects at Google
- Handling different browsers when writing directives (e.g. IE)
- Comparisons between different ways of structuring your application:
+ using controller vs scope
+ using directive prefix vs namespace
+ using element name vs attribute name vs class

Comments (9):

By anonymous    2017-09-20

Executive Summary:

In AngularJS, a child scope normally prototypically inherits from its parent scope. One exception to this rule is a directive that uses scope: { ... } -- this creates an "isolate" scope that does not prototypically inherit.(and directive with transclusion) This construct is often used when creating a "reusable component" directive. In directives, the parent scope is used directly by default, which means that whatever you change in your directive that comes from the parent scope will also change in the parent scope. If you set scope:true (instead of scope: { ... }), then prototypical inheritance will be used for that directive.

Scope inheritance is normally straightforward, and you often don't even need to know it is happening... until you try 2-way data binding (i.e., form elements, ng-model) to a primitive (e.g., number, string, boolean) defined on the parent scope from inside the child scope. It doesn't work the way most people expect it should work. What happens is that the child scope gets its own property that hides/shadows the parent property of the same name. This is not something AngularJS is doing – this is how JavaScript prototypal inheritance works. New AngularJS developers often do not realize that ng-repeat, ng-switch, ng-view, ng-include and ng-if all create new child scopes, so the problem often shows up when these directives are involved. (See this example for a quick illustration of the problem.)

This issue with primitives can be easily avoided by following the "best practice" of always have a dot '.' in your ng-models – watch 3 minutes worth. Misko demonstrates the primitive binding issue with ng-switch.

--AngularJS Wiki -- The Nuances of Scope Prototypal Inheritance


I tried to do the '.' notation in my scope but whenever I try to reference it like this:

$scope.moment.description = ""; 

It says "Cannot read property 'description' of undefined.

The code needs to create the object before assigning a value to a property:

$scope.moment = {};
$scope.moment.description = "";

//OR

$scope.moment = { description: "" };    

Original Thread

By anonymous    2017-09-20

Use property accessor bracket notation with the this context keyword:

<div ng-repeat="count in [3,4,5,6,7,8,9,10,11,12]" class="padding-top-10">
  <span>{{this["head"+count]}}</span>
</div>

With Angular Expressions the this keyword evaluates to the $scope of the expression.

Be aware that the ng-repeat directive creates child scopes and that this expression finds the value by prototypical inheritance. This can cause problems when using this in ng-model directives. (This issue with primitives can be easily avoided by following the "best practice" of always have a '.' in your ng-models)

For more information, see What are the nuances of scope prototypal / prototypical inheritance in AngularJS?.

Original Thread

By anonymous    2017-09-20

You can use md-radio-group and md-radio-button inside table exactly the way you did. The reason your code doesn't work is not obeying the "always use a dot rule".

this is a working example

Original Thread

By anonymous    2017-11-27

Core AngularJS directives such as ng-repeat, ng-switch, ng-view, ng-include and ng-if all create new child scopes. As a result, the form controller will attach its API to that child scope. In this case the uib-tabset directive is transcluding to a child scope.

To access form controls on the parent scope, use the ng-form directive to create a nested form:

<form name="top">
    <div ng-if="AngularExpression">
       <ng-form name="formA" novalidate>
           <input ng-model="userData.testA" required />
       </ng-form>
   </div>
</form>

<div ng-show="top.formA.$error.$required">
   ERROR: input required
</div>

Also it is important to follow the "best practice" of always have a dot, '.', in your ng-models.

For more information, see What are the nuances of scope prototypal / prototypical inheritance in AngularJS?.

Original Thread

By anonymous    2018-05-14

This issue with primitives can be easily avoided by following the "best practice" of always have a '.' in your ng-models http://www.youtube.com/watch?v=ZhfUv0spHCY&feature=youtu.be&t=30m – watch 3 minutes worth. Misko demonstrates the primitive binding issue with `ng-switch`.

Original Thread

By anonymous    2018-05-14

http://www.youtube.com/watch?v=ZhfUv0spHCY&feature=youtu.be&t=30m – watch 3 minutes worth. Misko demonstrates the primitive binding issue with `ng-switch`.

Original Thread

Popular Videos 590

Submit Your Video

If you have some great dev videos to share, please fill out this form.