I recently started using the (not so new) components for an old angular app. I'm trying to make some dumb components for trivial stuff like <button/>
s and the like.
For some reason, I can't seem to get one way bindings to work!
The level
binding in the difficultyButton
component (in difficult-button.js
) always returns undefined
, but the onLevelChosen
binding (again, in difficulty-button.js
) seems to have the callback that the options
component passed to it.
Do any of you see where I might've gone wrong?
Here is a jsbin link demonstrating this problem : http://jsbin.com/rixukuh/11/edit?html,js
Notice how the classes red
, green
and blue
never get applied because they could never catch hold of the value of vm.level
.
Also, the console always prints out LEVEL => undefined
, irrespective of what button is clicked.
FULL CODE
Here's the full code, if more context is needed.
options.tpl.html
<div class="full-page-cover">
<div class="options-grid">
<!-- some random markup -->
<div class="buttons-grid">
<difficulty-button
level="easy"
on-level-chosen="vm.chooseDifficulty(level)" >
I'm just here for having fun!
</difficulty-button>
<!-- some more `difficulty-buttons` -->
</div>
</div>
</div>
options.js
import angular from 'angular';
import DifficultyButtonModule from './difficulty-button.js';
import template from './options.tpl.html';
class OptionsController {
constructor() { /* ... */ }
chooseDifficulty(level) { /* ... */ }
}
const OptionsModule = angular.module('options', [DifficultyButtonModule.name])
OptionsModule.component('options', {
template,
controller: OptionsController,
controllerAs: 'vm'
});
export default OptionsModule;
difficulty-button.tpl.html
<button
ng-class="[
'uk-button uk-button-large',
{
easy: 'uk-button-default',
medium: 'uk-button-primary',
hard: 'uk-button-danger'
} [ vm.level ]
]"
ng-click="vm.onLevelChosen({ level: vm.level })"
ng-transclude>
</button>
difficulty-button.js
import angular from 'angular';
import template from './difficulty-button.tpl.html';
const DifficultyButtonModule = angular.module('difficultyButton', []);
DifficultyButtonModule.component('difficultyButton', {
template,
bindings: {
level: '<',
onLevelChosen: '&'
},
controllerAs: 'vm',
transclude: true
});
export default DiffButtonModule;
when you do this
level="easy"
you're binding against easy property in your scope (like $scope.easy
). Which of course does not exist. If you want to bind against the string value directly from your html, you need to use single quotes
level="'easy'"
and the same for the other levels. That will work fine.
If you still want to use bind against object, you will need to create them in them your scope. But since you need one way only, using string should work fine
Disclaimer: I haven't worked with components, so it might be that the explanation is incorrect. I have just worked with angularjs