Contributes to #2407 - Dropped the “2” in “Angular 2” and “angular2_*” where appropriate. - Did a partial sync of `_cache/guide/pipes.jade` - In quickstart, changed `Try changing the message to "Hello Angular 2!”` to `Try changing the message to "Hello Again Angular!”`.
		
			
				
	
	
		
			129 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			129 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
extends ../../../ts/_cache/guide/dependency-injection.jade
 | 
						|
 | 
						|
block includes
 | 
						|
  include ../_util-fns
 | 
						|
  - var _thisDot = '';
 | 
						|
 | 
						|
block ctor-syntax
 | 
						|
  .l-sub-section
 | 
						|
    :marked
 | 
						|
      We also leveraged Dart's constructor syntax for declaring parameters and
 | 
						|
      initializing properties simultaneously.
 | 
						|
 | 
						|
block injectable-not-always-needed-in-ts
 | 
						|
  //- The [Angular Dart Transformer](https://github.com/angular/angular/wiki/Angular-2-Dart-Transformer)
 | 
						|
  //- generates static code to replace the use of dart:mirrors. It requires that types be
 | 
						|
  //- identified as targets for static code generation. Generally this is achieved
 | 
						|
  //- by marking the class as @Injectable (though there are other mechanisms).
 | 
						|
 | 
						|
block always-include-paren
 | 
						|
  :marked
 | 
						|
    Always write `@Injectable()`, not just `@Injectable`.
 | 
						|
    A metadata annotation must be either a reference to a
 | 
						|
    compile-time constant variable or a call to a constant
 | 
						|
    constructor such as `Injectable()`.
 | 
						|
    
 | 
						|
    If we forget the parentheses, the analyzer will complain:
 | 
						|
    "Annotation creation must have arguments". If we try to run the
 | 
						|
    app anyway, it won't work, and the console will say
 | 
						|
    "expression must be a compile-time constant".
 | 
						|
 | 
						|
block real-logger
 | 
						|
  .l-sub-section
 | 
						|
    :marked
 | 
						|
      A real implementation would probably use the
 | 
						|
      [logging package](https://pub.dartlang.org/packages/logging).
 | 
						|
 | 
						|
block provider-shorthand
 | 
						|
  :marked
 | 
						|
    This is actually a shorthand expression for a provider registration
 | 
						|
    that creates a new instance of the
 | 
						|
    [Provider](../api/angular2.core/Provider-class.html) class:
 | 
						|
 | 
						|
block provider-ctor-args
 | 
						|
  - var _secondParam = 'named parameter, such as <code>useClass</code>' 
 | 
						|
  :marked
 | 
						|
    We supply two arguments (or more) to the `Provider` constructor.
 | 
						|
 | 
						|
block dart-diff-const-metadata
 | 
						|
  .callout.is-helpful
 | 
						|
    header Dart difference: Constants in metadata
 | 
						|
    :marked
 | 
						|
      In Dart, the value of a metadata annotation must be a compile-time constant.
 | 
						|
      For that reason, we can't call functions to get values
 | 
						|
      to use within an annotation.
 | 
						|
      Instead, we use constant literals or constant constructors.
 | 
						|
      For example, a TypeScript program will use the
 | 
						|
      object literal `{ provide: Logger, useClass: BetterLogger }`.
 | 
						|
      A Dart annotation would instead use the constant value 
 | 
						|
      `const Provider(Logger, useClass: BetterLogger)`.
 | 
						|
 | 
						|
block dart-diff-const-metadata-ctor
 | 
						|
  .callout.is-helpful
 | 
						|
    header Dart difference: Constants in metadata
 | 
						|
    :marked
 | 
						|
      Because Dart annotations must be compile-time constants,
 | 
						|
      `useValue` is often used with string or list literals.
 | 
						|
      However, `useValue` works with any constant object.
 | 
						|
 | 
						|
      To create a class that can provide constant objects,
 | 
						|
      ensure all its instance variables are `final`,
 | 
						|
      and give it a `const` constructor.
 | 
						|
      
 | 
						|
      Create a constant instance of the class by using `const` instead of `new`.
 | 
						|
 | 
						|
// - var stylePattern = { otl: /(useValue.*\))/gm };
 | 
						|
// +makeExample('dependency-injection/dart/lib/providers_component.dart','providers-9','', stylePattern)(format='.')
 | 
						|
 | 
						|
block non-class-dep-eg
 | 
						|
  span string, list, map, or maybe a function.
 | 
						|
 | 
						|
block config-obj-maps
 | 
						|
  | . They can be 
 | 
						|
  | <b><a href="https://api.dartlang.org/stable/dart-core/Map-class.html">Map</a></b>
 | 
						|
  | literals
 | 
						|
 | 
						|
block what-should-we-use-as-token
 | 
						|
  :marked
 | 
						|
    But what should we use as the token? 
 | 
						|
    While we _could_ use **[Map][]**, we _should not_ because (like
 | 
						|
    `String`) `Map` is too general. Our app might depend on several maps, each
 | 
						|
    for a different purpose.
 | 
						|
 | 
						|
    [Map]: https://api.dartlang.org/stable/dart-core/Map-class.html
 | 
						|
 | 
						|
  .callout.is-helpful
 | 
						|
    header Dart difference: Interfaces are valid tokens
 | 
						|
    :marked
 | 
						|
      In TypeScript, interfaces don't work as provider tokens.
 | 
						|
      Dart doesn't have this limitation;
 | 
						|
      every class implicitly defines an interface,
 | 
						|
      so interface names are just class names.
 | 
						|
      `Map` is a *valid* token even though it's the name of an abstract class;
 | 
						|
      it's just *unsuitable* as a token because it's too general.
 | 
						|
 | 
						|
block dart-map-alternative
 | 
						|
  :marked
 | 
						|
    As an alternative to using a configuration `Map`, we can define
 | 
						|
    a custom configuration class:
 | 
						|
 | 
						|
  +makeExcerpt('lib/app_config.dart (alternative config)','config-alt')
 | 
						|
 | 
						|
  :marked
 | 
						|
    Defining a configuration class has a few benefits. One key benefit
 | 
						|
    is strong static checking: we'll be warned early if we misspell a property
 | 
						|
    name or assign it a value of the wrong type.
 | 
						|
    The Dart [cascade notation][cascade] (`..`) provides a convenient means of initializing
 | 
						|
    a configuration object. 
 | 
						|
 | 
						|
    If we use cascades, the configuration object can't be declared `const` and
 | 
						|
    we can't use a [value provider](#value-provider). 
 | 
						|
    A solution is to use a [factory provider](#factory-provider).
 | 
						|
    We illustrate this next. We also show how to provide and inject the
 | 
						|
    configuration object in our top-level `AppComponent`:
 | 
						|
 | 
						|
    [cascade]: https://www.dartlang.org/docs/dart-up-and-running/ch02.html#cascade
 | 
						|
 | 
						|
  +makeExcerpt('lib/app_component.dart','providers')
 | 
						|
  +makeExcerpt('lib/app_component.dart','ctor')
 |