Simple $scope test not working - angularjs

I'm trying to do a simple $scope controller practice. The app should show the result expression if the text value is the correct one...
<scope-test>
<h2>My Name?</h2>
<input type="text" ng-model="text"/>
<p>{{text}} {{result}}</p>
</scope-test>
And this is the app...
angular.module('angular-tests', [])
.directive('scope-test', function(){
return{
restrict:'E',
controller: function($scope){
if ($scope.text === "alex") {
$scope.result = "is correct!";
} else {
$scope.result = "is not correct!";
}
}
};
});
Ng-model is the only thing working fine.
Thanks!

Each controller function called once per load (like a constructor). It means that you check your value only once at the start.
You need to create a function inside your controller, which will be ran by each change:
<scope-test>
<h2>My Name?</h2>
<input type="text" ng-model="text" ng-change="changeHandler" />
<p>{{text}} {{result}}</p>
</scope-test>
angular.module('angular-tests', [])
.directive('scope-test', function(){
return{
restrict:'E',
controller: function($scope){
$scope.changeHandler = function(){
if ($scope.text === "alex") {
$scope.result = "is correct!";
} else {
$scope.result = "is not correct!";
}
}
}
};
});

The most simple solution would be to include a watch in your directive.
Angular Code
var myApp = angular.module('myApp',[])
.directive('scopeTest', function(){
return{
restrict:'E',
controller: function($scope) {
$scope.$watch('text', function() {
if ($scope.text === "alex") {
$scope.result = "is correct!";
} else {
$scope.result = "is not correct!";
}
})
}
};
});
HTML Code
<scope-test>
<h2>My Name?</h2>
<input type="text" ng-model="text"/>
<p>{{text}} {{result}}</p>
</scope-test>
Hope it helps!
Here is the fiddle: http://jsfiddle.net/au2uL08u/

Also note that your directive name needs to be camelCase. Then when you place your directive inside the template, you use hyphens for each word that begins with a capital.
<scope-test>
<h2>My Name?</h2>
<input type="text" ng-model="text" ng-change="evaluateText()"/>
<p>{{text}} {{result}}</p>
</scope-test>
angular.module('angular-tests', [])
.directive('scopeTest', function(){
return{
restrict:'E',
controller: function($scope){
$scope.evaluateText = function () {
if ($scope.text === "alex") {
$scope.result = "is correct!";
} else {
$scope.result = "is not correct!";
}
};
$scope.evaluateText();
}
};
});

Related

Sharing scope data in controller

My spring mvc controller returns an object.
My scenario is:
On click of a button from one page say sample1.html load a new page say sample2.html in the form of a table.
In sample1.html with button1 and controller1--> after clicking button1-->I have the object(lets say I got it from backend) obtained in controller1.
But the same object should be used to display a table in sample2.html
How can we use this object which is in controller1 in sample2.html?
You can use a service to store the data, and inject it in your controllers. Then, when the value is updated, you can use a broadcast event to share it.
Here is a few example:
HTML view
<div ng-controller="ControllerOne">
CtrlOne <input ng-model="message">
<button ng-click="handleClick(message);">LOG</button>
</div>
<div ng-controller="ControllerTwo">
CtrlTwo <input ng-model="message">
</div>
Controllers
function ControllerOne($scope, sharedService) {
$scope.handleClick = function(msg) {
sharedService.prepForBroadcast(msg);
};
}
function ControllerTwo($scope, sharedService) {
$scope.$on('handleBroadcast', function() {
$scope.message = sharedService.message;
});
}
Service
myModule.factory('mySharedService', function($rootScope) {
var sharedService = {};
sharedService.message = '';
sharedService.prepForBroadcast = function(msg) {
this.message = msg;
this.broadcastItem();
};
sharedService.broadcastItem = function() {
$rootScope.$broadcast('handleBroadcast');
};
return sharedService;
});
JSFiddle demo
you can use factory to share data between controllers
<div ng-controller="CtrlOne">
<button ng-click="submit()">submit</button>
</div>
<div ng-controller="CtrlTwo">
{{obj}}
</div>
.controller('CtrlOne', function($scope, sampleFactory) {
$scope.sampleObj = {
'name': 'riz'
}; //object u get from the backend
$scope.submit = function() {
sampleFactory.setObj($scope.sampleObj);
}
})
.controller('CtrlTwo', function($scope, sampleFactory) {
$scope.obj = sampleFactory.getObj();
})
.factory('sampleFactory', function() {
var obj = {};
return {
setObj: function(_obj) {
obj = _obj;
},
getObj: function() {
return obj;
}
}
})

Trigger form submit automatically on partial/controller load

I have a user log into my AngularJS app and once they do a http.get retreives a dataset with some key values. One of those is a key that I need to post to a iframe to get it queued up for the right user (based on the key). Thus far I have this and it is not working.
HTML:
<form name="watchLiveForm" action="{{testingUrl}}" target="watch-live" method="post" ng-submit="controllsubmit()">
<label for="key">Company Software Key:</label>
<input type="text" name="key" id="key" ng-model="key">
<input type="submit">
</form>
<iframe name="watch-live" ng-src="{{testingUrl}}" width="100%" height="600"> </iframe>
Controller:
app = angular.module('angularWebApp.indexController', []);
app.controller('indexController', function($scope, $http, $rootScope, $sce) {
$scope.controllsubmit = function() {
console.log("I was called!");
};
if($scope.user !== undefined) {
if($scope.user.software_key.constructor === Array) {
$http.get('http://URL/api/' + $scope.user.software_key[1] + '/remotes').
success(function(data) {
if(data.id === 'error') {
console.log(data);
} else {
$scope.machineList = data;
$scope.key = $scope.user.software_key[1];
console.log($scope.user.software_key[1]);
console.log($scope.key);
$scope.testing = 'http://URL/settings';
$scope.testingUrl = $sce.trustAsResourceUrl($scope.testing);
}
}).
error(function(data) {
alert(data);
});
}
}
});
Directive:
angular.module('angularWebApp.indexDirectives', [])
.directive('form', function() {
return {
require: 'form',
restrict: 'A',
link: function(scope, element, attributes) {
var scopa = element.scope();
if (attributes.name && scopa[attributes.name]) {
scopa[attributes.name].$submit = function() {
// Parse the handler of submit & execute that.
var fn = $parse(attr.ngSubmit);
$scope.$apply(function() {
fn($scope, {$event: e});
});
};
}
}
};
});
After the user is logged in I call a http.get and obtain the software_key which I pass to the form (works). It just seems that getting the form to automatically submit is the issue as I want to made the inputs hidden eventually so they will not see the form as they do now. Any help is greatly appreciated!

Angular Js ng-model not updating variable in an inner function

I have the following code in my controller:
appControllers.controller('myCtrl', [ '$scope',
function($scope) {
$scope.timeFreeze = false;
$scope.ws = new WebSocket("ws://localhost:8080/ws");
$scope.ws.onopen = function() {
$scope.ws.send('{...}');
};
$scope.ws.onmessage = function (evt) {
var received_msg = JSON.parse(evt.data);
//...do something with the data...
console.log($scope.timeFreeze); // This is ALWAYS false!!! Why?
if ( $scope.timeFreeze === false) {
$scope.$apply();
} else {
console.log("Frozen!"); // This never runs!!!
}
};
$scope.ws.onclose = function() {
console.log("Connection is closed...");
};
}
]);
and in my html I have:
<div>
<label>Freeze?</label>
<input type="checkbox" ng-model="timeFreeze"/>
</div>
What is meant to happen is that when the checkbox is ticked, the code should output "Frozen!" in the console. Unfortunately this code is NEVER run! The $scope.timeFreeze is always false despite me setting the ng-model for the checkbox.
Posting the answer so it can be marked:
Try using dot notation. Something like ng-model="socket.timeFreeze" and $scope.socket.timeFreeze. JB Nizet used a better naming convention so I'm gong to borrow from him:
In your controller:
$scope.time = {freeze: false };
In your view:
<input type="checkbox" ng-model="time.freeze">

angularjs and calling function in the same object

I use two simple form with angularjs
<form ng-controller="ctrs.ctr1">
<input type="text" placeholder="Name" ng-model="name" />{{getName()}}
</form>
and
<form ng-controller="ctrs.ctr2">
<input type="text" placeholder="Name" ng-model="name" />{{getName()}}
</form>
and s small script for e.g showing name twice
var ctrs = {
nameTwoTimes: function(name) {
return name+" "+name;
},
ctr1: function($scope, $timeout) {
$scope.name = '';
$scope.getName = function() {
return $scope.name+" "+$scope.name;
};
},
ctr2: function($scope, $timeout) {
$scope.name = '';
$scope.getName = function() {
this.nameTwoTimes($scope.name);
};
}
};
How to use the function nameTwoTimes, that in calling it is not "undefined"? Thanks.
Like this:
var nameTwoTimes: function(name) {
return name+" "+name;
};
var ctrs = {
ctr1: function($scope, $timeout) {
$scope.name = '';
$scope.getName = function() {
return $scope.name+" "+$scope.name;
};
},
ctr2: function($scope, $timeout) {
$scope.name = '';
$scope.getName = function() {
nameTwoTimes($scope.name);
};
}
};

Accessing a service or controller in my link function - Angular.js

I have a directive, but I am having a problem access the controller and my service that is injected into it. Here is my directive:
angular.module('clinicalApp').directive('chatContainer', ['encounterService', function(encounterService) {
return {
scope: {
encounter: '=',
count: '='
},
templateUrl: 'views/chat.container.html',
controller: 'EncounterCtrl',
link: function(scope, elem, attrs, controller) {
scope.addMessage = function(message) {
//RIGHT HERE
scope.resetChat();
};
scope.resetChat = function() {
scope.chatText = '';
scope.updateCount(scope.chatText);
};
}
};
}]);
You can see that I am attaching a couple of functions to my scope inside the link function. Inside those methods, like addMessage, I don't have access to my controller or the service that is injected into the directive. How do I acceess the controller or service?
UPDATE
Here is the service:
angular.module('clinicalApp').factory('encounterService', function ($resource, $rootScope) {
var EncounterService = $resource('http://localhost:port/v2/encounters/:encounterId', {encounterId:'#id', port: ':8280'}, {
search: {
method: 'GET'
}
});
var newEncounters = [];
var filterTerms = {};
EncounterService.pushNewEncounter = function(encounter) {
newEncounters.push(encounter);
$rootScope.$broadcast('newEncountersUpdated');
};
EncounterService.getNewEncounters = function() {
return newEncounters;
}
EncounterService.clearNewEncounters = function() {
newEncounters = [];
}
EncounterService.setFilterTerms = function(filterTermsObj) {
filterTerms = filterTermsObj;
$rootScope.$broadcast('filterTermsUpdated');
EncounterService.getFilterTerms(); //filter terms coming in here, must redo the search with them
}
EncounterService.getFilterTerms = function() {
return filterTerms;
}
return EncounterService;
});
and the chat.container.html
<div class="span4 chat-container">
<h5 class="chat-header">
<span class="patient-name-container">{{encounter.patient.firstName }} {{encounter.patient.lastName}}</span>
</h5>
<div class="chat-body">
<div class="message-post-container">
<form accept-charset="UTF-8" action="#" method="POST">
<div class="text-area-container">
<textarea id="chatBox" ng-model="chatText" ng-keyup="updateCount(chatText)" class="chat-box" rows="2"></textarea>
</div>
<div class="counter-container pull-right">
<span class="muted" id="counter">{{count}}</span>
</div>
<div class="button-container btn-group btn-group-chat">
<input id="comment" class="btn btn-primary btn-small btn-comment disabled" value="Comment" ng-click="addMessage(chatText)"/>
</div>
</form>
<div messages-container messages="encounter.comments">
</div>
</div>
</div>
</div>
Here is Demo Plunker I played with.
I removed scope{....} from directive and added 2 values in controller and directive to see how they change regards to action.
JS
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.name = 'World';
// listen on any change of chatText in directive
$scope.$watch(function () {return $scope.chatText;},
function (newValue, oldValue) {
if (newValue == oldValue) {return;}
$scope.chatTextFromController = newValue;
}, true);
});
app.directive('chatContainer', ['encounterService', function(encounterService) {
return {
templateUrl: 'chat.container.html',
link: function(scope, elem, attrs) {
scope.countStart = scope.count;
scope.updateCount = function(chatText) {
alert('updateCount');
scope.count = scope.countStart - chatText.length;
};
scope.addMessage = function(message) {
alert('addMessage');
encounterService.sayhello(message);
scope.resetChat();
};
scope.resetChat = function() {
alert('resetChat');
scope.chatText = 'someone reset me';
scope.name = "Hello " + scope.name;
scope.updateCount(scope.chatText);
};
}
};
}]);
app.service('encounterService', function() {
var EncounterService = {};
EncounterService.sayhello = function(message) {
alert("from Service " + message);
};
return EncounterService;
});
HTML
<body ng-controller="MainCtrl">
<div chat-container></div>
<pre>chatText from directive: {{chatText|json}}</pre>
<pre>chatText from controller: {{chatTextFromController|json}}</pre>
<pre>name: {{name|json}}</pre>
</body>

Resources