read file directive with controller as - angularjs

I need some help. I build the following directve to translate docx file into html string.
(function(){
'use strict';
angular
.module('app.core')
.directive('uploadFile', uploadFile);
function uploadFile($rootScope, $parse){
var directive = {
restrict: "A",
scope:{result : '='},
controller: 'refertazioneController',
controllerAs: "vm",
link: linkFunction,
};
function linkFunction(scope, element, attrs, controller){
document.getElementById("document")
.addEventListener("change", handleFileSelect, false);
function handleFileSelect(event) {
readFileInputEventAsArrayBuffer(event, function(arrayBuffer) {
mammoth.convertToHtml({arrayBuffer: arrayBuffer})
.then(displayResult)
.done();
});
}
function displayResult(result) {
scope.vm.result = resutl.value;
/* document.getElementById("output").innerHTML = result.value;
var messageHtml = result.messages.map(function(message) {
return '<li class="' + message.type + '">' + escapeHtml(message.message) + "</li>";
}).join("");
document.getElementById("messages").innerHTML = "<ul>" + messageHtml + "</ul>";*/
}
function readFileInputEventAsArrayBuffer(event, callback) {
var file = event.target.files[0];
var reader = new FileReader();
reader.onload = function(loadEvent) {
var arrayBuffer = loadEvent.target.result;
callback(arrayBuffer);
};
reader.readAsArrayBuffer(file);
}
function escapeHtml(value) {
return value
.replace(/&/g, '&')
.replace(/"/g, '"')
.replace(/</g, '<')
.replace(/>/g, '>');
}
};
return directive;
}
})();
the problem is that i'm not able to retrivie the translate string in the controller, defined as follows:
(function(){
'use strict';
angular
.module('app.core')
.controller('refertazioneController', refertazioneController);
function refertazioneController($stateParams, refertationService, $window, examinationService, dataService, $scope){
var vm = this;
vm.prova="refertazioneController";
vm.tinymceModel = '';
vm.sospeso=true;
vm.datiDaRefertare = $stateParams;
vm.paziente = dataService.getPatient(vm.datiDaRefertare.patientId);
examinationService.getPatientExamsDef(vm.datiDaRefertare.patientId).then(function(r){
vm.subjectExam = r.data[0].data;
})
console.log(vm.paziente);
vm.currentUser = sessionStorage;
vm.tinymceOptions = {
onChange: function(e) {
// put logic here for keypress and cut/paste changes
},
inline: false,
slector: 'textarea',
// toolbar: 'undo redo | styleselect | bold italic | link image | print save cancel',
height: 500,
plugins : 'advlist autolink link image lists charmap print preview template save paste',
skin: 'lightgray',
theme : 'modern',
language:'it',
statusbar: false,
templates:[ {title: 'Titolo1', description: 'Descrizione1', content: '<p style="text-align: center;">'+
'<strong>A.S.L. 02 LANCIANO-VASTO-CHIETI</strong>'+
'</p>'},
{title: 'Titolo2', description: 'Secondo referto', url: 'sections/refertazione/referto1.html'}
]
};
vm.html = {};
//vm.html.content = '<p>qui per esempio ci va il template che mi ridà il back end</p><h2>altra roba</h2>';
refertationService.openRefert(1,2);
refertationService.closeRefert(1,2);
refertationService.saveRefert(1,2);
/* vm.testoHtml = "";*/
}
})();
I thought that the line : scope.vm.result = result.value was able to bind the string to my controller and then that i was able to render it in the view as refertazione.result (refertazione is the name of my controller). But this not works, where I'm wrong?

A slightly better pattern that relies on events. You could pull this same pattern off with a scope variable that is two way.
Idea is you use an event to tell the controller data has changed.
function uploadFile($rootScope, $parse) {
var directive = {
restrict: "A",
scope: {},
link: linkFunction,
};
function linkFunction(scope, element, attrs) {
var fn = $parse(attrs.uploadFile);
element.on('change', function(onChangeEvent) {
var reader = new FileReader();
console.log(reader);
reader.onload = function(onLoadEvent) {
$rootScope.$broadcast('fileupdate', onLoadEvent.target.result);
};
reader.readAsText((onChangeEvent.srcElement || onChangeEvent.target).files[0]);
});
}
return directive;
}
Inside of your controller you would listen for the fileupdate event.
//inside your controller:
$scope.$on('fileupdate', showContent);
function showContent(event, $fileContent){
vm.content = $fileContent;
}

Related

Error: [ng:areq] Argument 'AddInstallationCtrl' is not a function, got Object

i cant find my fail :(
can help me?
in my project i have:
controller principal
define([
"./directives/subscribe",
"./controllers/subscribe",
"./controllers/script",
"angular",
"../models/app.models",
"../login/app.login",
], function (directives, controllers) {
var module = angular.module("app.matrix", ["app.models", "app.login"]).config(['$routeProvider', function ($routeProvder) {
$routeProvder
.when('/matrix', {
templateUrl: 'modules/matrix/templates/main.html',
controller: 'MatrixCtrl'
})
.when('/modals', {
templateUrl: 'modules/matrix/templates/index.html',
controller: 'AddInstallationCtrl'
});
}]);
module = directives.subscribe(module);
return controllers.subscribe(module);
(function () {
"use strict";
var app = angular.module('myApp', [
'ap.lateralSlideMenu',
]);
// service
app.service('number', function () {
return {
isPositive: function (operationPrice) {
return String(operationPrice).indexOf("-") == -1;
}
};
});
})
();
});
controller Secondary
define([
"./matrix",
"./sidebar",
"./script"
], function (matrix, sidebar, script) {
return {
subscribe: function (app) {
app.controller('MatrixCtrl', matrix).controller('SidebarCtrl', sidebar);
app.controller('AddInstallationCtrl', script);
app.directive('sidebarDirective', function () {
return {
link: function (scope, element, attr) {
scope.$watch(attr.sidebarDirective, function (newVal) {
if (newVal) {
element.addClass('show');
return;
}
element.removeClass('show');
});
}
};
});
return app;
}
};
});
Controller Finaly
define(["angular"], function () {
// Code goes here
var app = angular.module('myApp', ['ngAnimate', 'ngSanitize']);
app.config([
'$compileProvider',
function ($compileProvider) {
$compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|ftp|mailto|chrome-extension):/);
// Angular before v1.2 uses $compileProvider.urlSanitizationWhitelist(...)
}
]);
app.directive('modalDialog', function ($window, $templateCache, $compile, $http) {
return {
restrict: 'EA',
scope: {
show: '=',
modalUser: '=',
saveUser: '&',
templateUser: '#'
},
replace: true, // Replace with the template below
//transclude: true, // we want to insert custom content inside the directive
link: function (scope, element, attrs) {
$http.get(scope.templateUser, { cache: $templateCache }).success(function (tplContent) {
element.replaceWith($compile(tplContent)(scope));
});
scope.dialogStyle = {};
if (attrs.width) {
scope.dialogStyle.width = attrs.width + '%';
scope.dialogStyle.left = ((100 - attrs.width) / 2) + '%';
}
if (attrs.height) {
scope.dialogStyle.height = attrs.height + '%';
scope.dialogStyle.top = ((100 - attrs.height) / 2) + '%';
}
scope.hideModal = function () {
scope.show = false;
};
scope.clone = function (obj) {
if (obj === null || typeof obj !== 'object') {
return obj;
}
var temp = obj.constructor(); // give temp the original obj's constructor
for (var key in obj) {
temp[key] = scope.clone(obj[key]);
}
return temp;
};
var tempUser = scope.clone(scope.modalUser);
scope.save = function () {
scope.saveUser(scope.modalUser);
scope.show = false;
};
scope.cancel = function () {
scope.modalUser = scope.clone(tempUser);
scope.show = false;
};
}
//template: "<div class='ng-modal' ng-show='show'><div class='ng-modal-overlay'></div><div class='ng-modal-dialog' ng-style='dialogStyle'><div class='ng-modal-close' ng-click='hideModal()'>X</div><div class='ng-modal-dialog-content' ng-transclude></div></div></div>"
//templateUrl: 'my-customer.html'
//templateUrl: scope.templateUser
};
});
app.controller('AddInstallationCtrl', function ($scope, $window) {
$scope.modalShown = false;
$scope.modalShown2 = false;
$scope.user = { name: "Mara", surname: "Sanchez", shortKey: "1111" };
$scope.userMod = {};
$scope.toggleModal = function () {
$scope.modalShown = !$scope.modalShown;
};
$scope.toggleModal2 = function () {
$scope.modalShown2 = !$scope.modalShown2;
};
$scope.saveUser = function (usr) {
$scope.userMod = usr;
$window.alert('Desde metodo SALVAR del controller fuera de la ventana: ' + $scope.userMod.shortKey);
}
});
});
With the first controller I declare that the url: modules / matrix / templates / index.html
It is managed by the AddInstallationCtrl driver
With the second controller I declare that
The application has the AddInstallationCtrl driver
And that the controller is in the variable script
App.controller ('AddInstallationCtrl', script);
In the final controller I declare all the functions that I want to execute the letter
Even there is right, right?
Because when you entered modules / matrix / templates / index.html
Does it tell me that AddInstallationCtrl is not a controller?

isolate scope communication from directive to directive?

I am new to AngularJS and got confused with directive concept.
I am updating scope.markers in my second directive via $scope.delete function but changes are not reflecting on first directives,as I am using two way data binding isolate scope, so it should reflect. any solution will be a great help.
I have my first directive as:
app.directive('damageDiagram', function () {
return {
retrict: 'AE',
scope: {
imgsrc: '=', markers: '=', pointsrc: '=', dtype:'='
},
templateUrl: 'app/components/inspections/damage-diagram.html',
link: function (scope, element, attrs) {
}
}
});
and second directive as:
app.directive('damageMarker', function ($mdDialog,inspectionService,$timeout) {
return {
restrict: 'AE',
require: '?^damageDiagram',
scope: {
marker: '=',
pointsrc: '=',
dtype:'=',
markers: '='
},
template: '<img ng-src="{{pointsrc}}" />',
link: function (scope, elem, attr) {
elem.on("click",function(e){
showDialog();
function showDialog($event) {
var parentEl = angular.element(document.body);
$mdDialog.show ({
parent: parentEl,
targetEvent: $event,
template:
'<form name="clientForm" novalidate >'+
'<md-dialog aria-label="List dialog">' +
' <md-dialog-content>'+
'<md-input-container>'+
'<md-select ng-model="dtypeValue" class="dialog-close" placeholder="Select dtype">'+
'<md-option ng-repeat="opt in dtype">{{opt}}</md-option>'+
'</md-select>'+
'</md-input-container>'+
'<md-input-container class="md-block">'+
'<label>Comment</label>'+
'<input required name="name" ng-model="comment" class="dialog-close">'+
'<div ng-messages="clientForm.name.$error">'+
'<div ng-message="required">This is required.</div>'+
'</div>'+
'</md-input-container>'+
' </md-dialog-content>' +
' <div class="md-actions" layout="row" layout-align="end center">' +
' <md-button ng-click="closeDialog()" class="md-primary">' +
' Close' +
' </md-button>' +
'<md-button ng-disabled="clientForm.$invalid" ng-click = "save()" class="md-primary">'+
'Save'+
'</md-button>'+
'<md-button ng-disabled="clientForm.$invalid" ng-click = "delete()" class="md-primary">'+
'Delete'+
'</md-button>'+
' </div>' +
'</md-dialog>'+
'</form>',
controller: DialogController
});
function DialogController($scope, $mdDialog) {
$scope.dtypeValue = scope.dtype[scope.marker.dtype.toUpperCase()];
$scope.dtype = scope.dtype;
$scope.comment = scope.marker.comment;
$scope.marker = scope.marker;
$scope.closeDialog = function() {
$mdDialog.hide();
}
$scope.save = function(){
console.log($scope.marker.id);
console.log($scope.dtypeValue);
console.log($scope.comment);
var dataSend = {};
dataSend.id = $scope.marker.id;
dataSend.comment = $scope.comment;
for(var key in $scope.dtype) {
if($scope.dtype[key] == $scope.dtypeValue) {
dataSend.dtype = key;
}
}
inspectionService.updateDiagram(dataSend).then(function(response){
console.debug("response ; "+response);
$mdDialog.hide();
scope.marker.id = response.id;
scope.marker.comment = response.comment;
scope.marker.dtype = response.dtype;
});
}
$scope.delete = function(){
var dataSend = {};
dataSend.id = $scope.marker.id;
var param = {};
param.inspection=$scope.marker.inspection;
inspectionService.deleteDiagramMarker(dataSend).then(function(response){
inspectionService.getDiagram(param).then(function(response){
$timeout(function() {
scope.$apply(function(){
scope.markers = response.results;
})
},2000);
console.debug("response ; "+response);
$mdDialog.hide();
});
});
}
}
}
});
console.log(scope.marker.top, scope.marker.left, elem);
}
}
});
My html code for damage-diagram directive is as follows:
<damage-diagram imgsrc="imgsrc" pointsrc="pointsrc" dtype="dtype"
markers="inspection.damage_diagram">
</damage-diagram>
and my html code for damage-directive is as follow:
<div style="position:relative">
<img id="23467129" ng-src="{{imgsrc}}" style="position:relative" width="100%" />
<div ng-repeat="marker in markers"
marker="marker"
markers="markers"
dtype="dtype"
pointsrc="pointsrc"
damage-marker>
</div>
</div>
controller is as follows:
app.controller('InspectionDetailCtrl', ['$scope', 'inspectionService', '$stateParams', 'Restangular','$rootScope',
function ($scope, inspectionService, $stateParams, Restangular, $rootScope) {
$scope.updateDamageImage = {};
$scope.insp_id = $stateParams.inspId;
$scope.damageImagesShow = false;
$scope.comments = [];
$scope.types = [];
$scope.selectTypeDelete = false;
$scope.commentDelete = false;
$scope.selectTypeDeleteBefore = true;
$scope.commentDeleteBefore = true;
init($scope.insp_id);
console.log("Fetching details for scope", $scope.insp_id);
function init(insp_id)
{
inspectionService.inspections.customGET(insp_id, {type: 'full'})
.then(function (data) {
$scope.inspection = data;
}, function (err) {
$scope.inspection = null;
});
}
$scope.pointsrc="app/components/inspections/pointer.png";
$scope.dtype = {
'S': 'Scratch (minor)',
'DS': 'Deep Scratch',
'D': 'Dents',
'WD': 'Wheel Damage',
'CW': 'Cracked Window',
'FT': 'Flat Tire',
'BL': 'Broken (lights)'
};
}]);
First of all two way binding in directive doesn't works like that any change reflected in main controller can be seen in directive but not other way any change in directive won't be reflected in main controller.
But there is a solution you can create an object in main controller
var x={};
x.value='to be passed in directive'
then you use same variable in directive since only once instance of object is created so any change in any directive will be reflected everywhere.

Calling parent directive method from child directive through attrs

This is the scenario :
<export-team>
<ul>
<li>
<button buy-ticket="{{data}}" buy-callback="onBuyTicket()">buy</button>
</li>
<li>
<button buy-ticket="{{data}}" buy-callback="onBuyTicket()">buy</button>
</li>
</ul>
</export-team>
The buyTicket directive
(function() {
'use strict';
angular
.module('myApp')
.directive('buyTicket', buyTicket);
/** #ngInject */
function buyTicket($parse, ngDialog, authService, APPCONFIG, $rootScope, shareToken, contestsFactory, shareCurrentTicket, shareIdSession, shareSessionAAMS, $location) {
var vm = this;
var directive = {
restrict: 'A',
link : function(scope, element, attributes) {
var buyCompatible = attributes['buyCompatible'];
function addZero(i) {
if (i < 10) {
i = "0" + i;
}
return i;
}
var buyTicket = function(contest) {
var d = new Date();
var y = d.getFullYear();
var m = addZero(d.getMonth()+1);
var day = addZero(d.getDate());
var h = addZero(d.getHours());
var min = addZero(d.getMinutes());
var s = addZero(d.getSeconds());
var date = ''+y+m+day+h+min+s+'';
var transactionId = $rootScope.TRANSACTIONID;
var currentTOKEN = shareToken.get();
var data = {
idSessione:currentTOKEN, // ->TOKEN
userAgent:navigator.userAgent,
sessioneAAMS:contest.aams_session_id,
gameId:APPCONFIG.GAME_ID,
transactionId:transactionId,
dateTime:date,
buyIn:contest.buy_in
}
var dialogLoading = ngDialog.open({
closeByDocument : false,
closeByEscape : false,
showClose : false,
id : 'ft-modal-loading',
controller: ['$scope', function($scope){
$scope.bodyUrl = 'app/components/modals/body/loading.html';
$scope.title = 'Acquisto Ticket';
$scope.error = 'Il sistema sta procedendo all\'acquisto del ticket';
}]
});
contestsFactory.buyTicket(data).success(function(response){
dialogLoading.close();
if (response.esito == "0") {
if (!buyCompatible) {
shareCurrentTicket.set(response.ticketSogei);
shareSessionAAMS.set(contest.aams_session_id);
shareIdSession.set(contest.id_session);
$location.path('my-contests/'+contest.id_contest+'/'+contest.contest_status);
}
} else {
var message = response.descrizione;
var ids = ngDialog.getOpenDialogs();
var dialogError = ngDialog.open({
id : "ft-modal-error-2",
controller: ['$scope', function($scope){
$scope.bodyUrl = 'app/components/modals/body/error.html';
$scope.title = 'Errore';
$scope.error = message;
}]
});
}
})
.error(function(){
var dialogErrorNotEndled = ngDialog.close('ft-modal-loading');
ngDialog.open({
id : 'ft-modal-error',
controller: ['$scope', function($scope){
$scope.bodyUrl = 'app/components/modals/body/error.html';
$scope.title = 'Errore';
$scope.error = 'Il servizio non è attualmente disponibile';
}]
});
})
}
var openConfirmBuyTicket = function(contest) {
contest = JSON.parse(contest);
if (ngDialog.isOpen('ft-modal-contest-detail')) {
ngDialog.close('ft-modal-contest-detail');
};
if (!authService.isLogged()) {
ngDialog.open({
controller: ['$scope', function($scope){
$scope.bodyUrl = 'app/components/modals/body/not_logged.html';
$scope.title = 'Spiacenti';
$scope.error = 'Devi essere loggato per poter partecipare ad un contest';
}]
});
} else {
ngDialog.openConfirm({
controller: ['$scope', function($scope){
$scope.title = 'CONFERMA';
$scope.bodyUrl = 'app/components/modals/body/confirm_buy.html';
$scope.contest_name = contest.name_contest;
$scope.buy_in = contest.buy_in;
$scope.currency = APPCONFIG.CURRENCY_SYMBOL;
}],
}).then(function (confirm) {
buyTicket(contest);
}, function(reject) {
});
}
}
element.on('click', function(e){
var contest = attributes['buyTicket'];
openConfirmBuyTicket(contest);
})
}
};
return directive;
}
})();
The export directive
(function() {
'use strict';
angular
.module('myApp')
.directive('exportTeam', exportTeam);
/** #ngInject */
function exportTeam(contestsFactory, ngDialog, APPCONFIG, formatDateFactory) {
var vm = this;
var directive = {
restrict: 'AE',
transclude: true,
controller : function($scope) {
$scope.test = function() {
alert('hey');
}
},
link : function(scope, element, attributes) {
element.on('click', function(e){
var ticket = attributes['exportTeam'];
var id_session = attributes['idsession'];
scope.openExportTeamDialog(ticket, id_session, false);
})
scope.openExportTeamDialog = function(ticket, aams_session_id, afterSave) {
ngDialog.open({
id : 'ft-modal-exportTeam-detail',
className : 'ngdialog ngdialog-theme-default ft-dialog-exportTeam',
controller: ['$scope', 'contestsFactory', 'APPCONFIG', function($scope, contestsFactory, APPCONFIG){
$scope.title = "Aggiungi contest compatibili";
$scope.bodyUrl = 'app/components/modals/body/exportTeam.html';
$scope.contentLoading = true;
$scope.currency = APPCONFIG.CURRENCY_SYMBOL;
$scope.afterSave = afterSave;
$scope.CompatibleContests = [];
contestsFactory.getCompatibleContests(ticket).then(function(response){
angular.forEach(response.data[0], function(item, i){
var multientryOptions = [];
if(item.multientry > 1) {
item.isMultientry = false;
var n = parseInt(item.multientry);
for (i = 1; i <= n; i++) {
multientryOptions.push({
text : i+" team",
value : i
})
}
item.multientryOptions = multientryOptions;
item.multientryOptionSelected = multientryOptions[0];
}else{
item.isMultientry = true;
};
})
$scope.CompatibleContests = response.data[0];
$scope.contentLoading = false;
})
}]
});
}
scope.openExportTeamDialog('N3E94100A725F9QG', 'M3E921013C6DCFCT', false);
}
};
return directive;
}
})();
The buy-ticket directive makes an http call, on the response i want to be able to call the onBuyTicket method of the <export> directive.
I'm trying to understand the best way to do that.
Thanks everyone
This sample show to you how can call an function from your directive
In this sample you can see we just insert data in our directive, and then we handle the data and other action in the directive.
var app = angular.module("app", []);
app.controller("ctrl", function ($scope) {
$scope.dataFromYourController = [
{ name: "Concert Jennifer", value: 200 },
{ name: "007", value: 100 }
];
})
.directive("export", function () {
var template = "<div>" +
"<ul>" +
"<li ng-repeat=\"array in arrays\">" +
"<button ng-click=\"onBuyTicket()\">buy Ticket {{array.name}}</button><hr>" +
"</li>" +
"</ul>" +
"</div>";
return {
restrict: "E",
template: template,
scope: {
data: "="
},
link: function (scope, elem, attrs, ngModel) {
scope.arrays = scope.data;
scope.onBuyTicket = function () {
alert("calling function from directive");
}
}
};
})
<!doctype html>
<html ng-app="app" ng-controller="ctrl">
<head>
</head>
<body>
<h1>call action from your directive</h1>
<export data="dataFromYourController"></export>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
</body>
</html>
#eesdil
var directive = {
restrict: 'AE',
transclude: true,
controller : function($scope) {
$scope.onBuyTicket = function() {
alert('hey');
}
}
}
Ho can I call that from the buy-ticket directive ?
Use the $parent
<button buy-ticket="{{data}}" buy-callback="$parent.onBuyTicket()">buy</button>
So the expor directive something like:
var directive = {
restrict: 'AE',
template: '<ng-tansclude></ng-transclude>',
transclude: true,
controller : function($scope) {
$scope.onBuyTicket = function() {
alert('hey');
}
}
}
UPDATED:
see the plunker:
https://plnkr.co/edit/fmyJ4oPLvTiI0TzO7h1b?p=preview
It really depends what you can call and what you cannot based on the scopes... here if you would remove the scope from the export directive would work without the $parent also as export would share the same scope as the parent (main view)
The best way to communicate events from a child directive to a parent directive (or controller) is to use the $emit method of the scope.
What you want to do is take an ng-click event, get additional information with an $http call, and $emit an event with the additional information to be used by your parent directive (or controller).
HTML
<button buy-ticket="data" ng-click="onBuyTicket()">buy</button>
The directive:
angular.module("myApp").directive("buyTicket", function($http) {
function linkFn(scope,elem,attrs) {
scope.onBuyTicket = function() {
var buyData = scope.$eval(attrs.buyTicket);
var url = someFunction(buyData);
$http.get(url).then (function (response) {
var httpData = response.data;
scope.$emit("buyTicket.click", buyData, httpData);
});
};
};
return {
restrict: "AE",
link: linkFn
};
});
In the parent controller:
$scope.$on("buyTicket.click", function (buyData, httpData) {
console.log(buyData);
console.log(httpData);
});
Notice that I used the $eval method to get the data from the variable named by the buy-ticket attribute.
When choosing a name for the event, I recommend including the name of the directive in the event's name. It makes it clear the source of the event and is unlikely to be duplicated elsewhere.

angularjs directive 2 way binding not working

Here is my directive, it's simple task is to Locale Date String time:
.directive('localeDateString',['$window', function ($window) {
return {
restrict: 'E',
replace: true,
scope: {
time: '='
},
template: '<span>{{timeLocal}}</span>',
link: function ($scope, $element) {
if ($scope.time != null) {
profileDate = new Date($scope.time);
var cultureCode = $window.ApiData.CultureCode;
$scope.timeLocal = profileDate.toLocaleDateString(cultureCode);
}
}
};
}])
Usage in HTML:
<li ng-repeat="note in profile.AccountProfile.Notes" class="noteItem">
<locale-date-string time="note.Created" ></locale-date-string>
<span>{{note.UserName}}</span>
<!-- other stuff .. -->
</li>
When I'm loading the object "profile" from JSON everything is OK
the problem is when i change "note.Created" from controller - the directive seem not to work(other members of Note are updating ok):
In the controller:
DataService.updateProfileRemark(objRemark)
.then(function (response) {
// all is ok;
var profileIndex = $scope.ProfileList.indexOf(profile);
var noteIndex = $scope.ProfileList[profileIndex].AccountProfile.Notes.indexOf(note);
// this is working:
$scope.ProfileList[profileIndex].AccountProfile.Notes[noteIndex].UserName = objRemark.UserName;
// this is not:
$scope.ProfileList[profileIndex].AccountProfile.Notes[noteIndex].Created = Date.now();
},
function (errResponse) {
// handle err
}
);
For example, here is the scope before "updateProfileRemark":
and after:
Why the 2 way binding not working?
Thanks.
link is only executed once. If you want to setup two-way binding between $scope.timeLocal and $scope.time, setup a $watch:
link: function ($scope, $element) {
$scope.$watch('time', function(newTime) {
if (newTime != null) {
var profileDate = new Date(newTime);
var cultureCode = $window.ApiData.CultureCode;
$scope.timeLocal = profileDate.toLocaleDateString(cultureCode);
}
});

$watch in a directive not working

Any reason my $scope.$watch isn't working? When I type, I don't see the updates in the console.
(function () {
'use strict';
wikiApp.directive('wikiMarkdownEdit', ['pathSvc', function (pathSvc) {
var getFullPath = pathSvc.getFullPath;
return {
restrict: 'E',
templateUrl: getFullPath('html/directives/markdownEdit.html'),
replace: true,
scope: {
model: '=',
formId: '#',
rows: '#',
placeholder: '#'
},
controller: function($scope, $sce, $attrs, $log) {
var converter = new Showdown.converter();
$scope.showPreview = false;
/**
* Keep the preview up to date
*/
$scope.$watch('model', updateHTML);
var updateHTML = function() {
var html = converter.makeHtml($scope.model || '');
console.log(html);
// jQuery('#' + $scope.formId + 'Preview').html('1111');
};
updateHTML();
/**
* Sync the height of the preview div with the textarea
**/
var lastHeight = 0;
var getHeight = function() {
var newHeight = jQuery('#' + $scope.formId).outerHeight();
if (lastHeight === newHeight || newHeight < 20) {
setTimeout(getHeight, 100);
return;
}
lastHeight = newHeight;
jQuery('#' + $scope.formId + 'Preview').height(newHeight);
setTimeout(getHeight, 100);
};
getHeight();
/**
* Toggle preview button callback
*/
$scope.togglePreview = function() {
$scope.showPreview = !$scope.showPreview;
};
}
};
}]);
})();
try to change var updateHTML to function updateHTML, you can't use a function defined with var before the definition.
another way recommended:
function updateHTML() {
var html = converter.makeHtml($scope.model || '');
console.log(html);
};
$scope.$watch(function() {
return $scope.model;
}, updateHTML);
One more thing, in your directive scope, did you mean model to be bounded to ngModel? If so, try this approach:
...
scope: {
ngModel: '='
},
...
Or
...
scope: {
model: '=ngModel'
},
...

Resources