OK so I am trying to make a simple chat widget directive and I want it to be dynamically created wherever I want it on my app ie I do not want a hard coded solution. So I want the directive to be created from a service and therefore have its scope variables set via service helper methods. I think I see a few examples of this in some angularjs material directives for example I want to do something like:
$mdToast.simple()
.textContent('Marked as read')
.action('UNDO')
but instead my chat widget will be like:
$chatWidget.setParent(parent).setUser(user).setMessages(messages);
Here is an extremely simplified version of the directive so far:
angular
.module('app')
.directive('reChat', function ($chatWidget) {
return {
restrict: 'E',
replace: true,
template:
'<div id="chat-widget-container"><div id="chat-widget-header">User.name</div>'+
'<div id="chat-widget-body"<div ng-repeat="message in reMessages"><div>' +
'<p> {{message.body}} </p></div></div></div>' +
'<textarea ng-model="messageToSend" id="message-to-send" placeholder ="Type your message" rows="3"></textarea>' +
'<button class="btn btn-default" ng-click="sendMessage()">Send</button></div>'
,
scope: {
reMessages: '=',
reParent: '<',
reUser: '<'
},
link: function (scope, element, attrs) {
scope.sendMessage = function () {
//logic here...
};
};
});
So how do I set the three scope variables in my directive above (reMessages, reParent, reUser) from the following factory?
angular
.module('app')
.factory('$chatWidget', function ($document, $compile, $controller, $http, $rootScope, $q, $timeout) {
return {
// functions
}
})
Any help greatly appreciated.
In general, to set a directive scope property from a service, simply assign it:
app.directive('reChat', function ($chatWidget) {
return {
scope: {
reMessages: '=',
reParent: '<',
reUser: '<'
},
link: function (scope, element, attrs) {
scope.reMessages=$chatWidget.reMessages;
//OR asynchronously
$chatWidget.getReMessages()
.then(function(reMessages) {
scope.reMessages = reMessages;
}).catch(function(error) {
console.log(error);
}};
},
};
})
Since one-way <
binding was introduced with V1.5, the AngularJS team recommends that two-way =
binding be avoided. For inputs, use one-way <
bindings and attribute @
bindings. For outputs, use expression &
bindings which function as callbacks to component events. The general rule should be to never change a parent object or array property from the component. This will make transition to Angular 2+ easier.
For more information, see AngularJS Developer Guide - Component-based application architecture.