Skip to content
This repository has been archived by the owner on Apr 12, 2024. It is now read-only.

.component template function not accepting annotations #13645

Closed
ninjasort opened this issue Dec 28, 2015 · 7 comments
Closed

.component template function not accepting annotations #13645

ninjasort opened this issue Dec 28, 2015 · 7 comments

Comments

@ninjasort
Copy link

Given a component:

import angular from 'angular';

export default {
  bindings: {},
  template: [
    '$element',
    '$attrs', 
    function ($element, $attrs) {
      return [
         '<div class="search-input">',
        '</div>'
      ].join('');
    }
  ],
  controller: [
    'Search', 
    function (Search) {}
  ]
};

The controller works, however the template doesn't accept the annotations and returns a string.

@Narretz
Copy link
Contributor

Narretz commented Dec 31, 2015

This is coming in 1.5.0

@Narretz Narretz closed this as completed Dec 31, 2015
@karlhorky
Copy link

Is there a workaround that we can use until then? Manual injection or something? Or even copying the relevant parts of 1.5.0?

I've been using Todd Motto's polyfill along with ng-strict-di and I can't seem to find a way to make it work...

@gkalpak
Copy link
Member

gkalpak commented Jan 18, 2016

@karlhorky, it sounds more like an issue for https://github.com/toddmotto/angular-component.
Beware that .component() is still a feature under development (although pretty clode to final), so make sure your polyfills keep up with the breaking changes or you might run into surprizes when trying to upgrade to 1.5.

@karlhorky
Copy link

Okay thanks @gkalpak, I've opened toddmotto/angular-component#11

@toddmotto
Copy link

Anyone using the component() polyfill, I've added support for Array dependency annotation under release 0.0.5, code here: toddmotto/angular-component@28ff08e

Demo for annotated code.

This allows for:

// Array annotations with minification
template: ['$element', '$attrs', function template(a, b) {
  console.log(a, b); // $element, $attrs
  return [
    '<div class="counter">',
      '<p>Counter component</p>',
      '<input type="text" ng-model="counter.count">',
      '<button type="button" ng-click="counter.decrement();">-</button>',
      '<button type="button" ng-click="counter.increment();">+</button>',
    '</div>'
  ].join('');
}]
// No annotations with automated minification (see source code `isArray` ternary + annotations)
template: function template(a, b) {
  console.log(a, b); // $element, $attrs
  return [
    '<div class="counter">',
      '<p>Counter component</p>',
      '<input type="text" ng-model="counter.count">',
      '<button type="button" ng-click="counter.decrement();">-</button>',
      '<button type="button" ng-click="counter.increment();">+</button>',
    '</div>'
  ].join('');
}
// Basic template String
template: [
  '<div class="counter">',
    '<p>Counter component</p>',
    '<input type="text" ng-model="counter.count">',
    '<button type="button" ng-click="counter.decrement();">-</button>',
    '<button type="button" ng-click="counter.increment();">+</button>',
  '</div>'
].join('')

@toddmotto
Copy link

@petebacondarwin Note on minification against this:

In the link function of Directives, you can use any name such as scope instead of $scope:

// works
link($scope) {}
// also works
link(scope) {}

I've added this same behaviour to the component() polyfill here to automatically annotate, would this be worth aligning in the Angular core as well? ... Assuming you need to declare template($element) {...} and template(element) {...} breaks.

Small comments below:

function makeInjectable(fn) {
  var isArray = angular.isArray(fn);
  if (angular.isFunction(fn) || isArray) {
    return function (tElement, tAttrs) {
      // isArray check, annotates the function if it's a function, or leaves as DI Array syntax
      return $injector.invoke((isArray ? fn : [
        '$element',
        '$attrs',
        fn
      ]), this, {
        $element: tElement,
        $attrs: tAttrs
      });
    };
  } else {
    return fn;
  }
}

This allows you to:

template: function(a, b) {
  console.log(a, b); // $element, $attrs
}

@petebacondarwin
Copy link
Member

@toddmotto thanks for the idea but I am concerned that mixing injected and non-injected APIs is too dangerous.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants