calling function within td element to set the text - angularjs

I am trying to call a function within a <td> element that is part of a ng-repeat. Any ideas how to get this to work? I have tried so many things and no joy. The issue is the cartperf.perf_desc binding.
<table class="table table-striped table-condensed" >
<tr ng-repeat="cartperf in $ctrl.cartSummary">
<td class="cs-cart-sum-td">{{cartperf.id}}</td>
<td class="cs-cart-sum-td" ng-bind="$ctrl.myNewHtml(cartperf.perf_desc)"></td>
<td class="cs-cart-sum-td">{{cartperf.perf_dt}}</td>
<td class="cs-cart-sum-td">{{cartperf.theater}}</td>
<td class="cs-cart-sum-td">{{cartperf.num_tkts}}</td>
<td class="cs-cart-sum-td">{{cartperf.due_amt}}</td>
<td class="cs-cart-sum-td">
<button type="button" data-perf='cartperf' class="btn btn-link cs-btn-delete" ng-click="$ctrl.confirmDelete(cartperf)">{{cartperf.RemoveBtnTxt}}</button>
</td>
</tr>
</table>
Controller that drive the template
function cartSummaryController() {
this.$onInit = function () {
//Get content from Parent
this.globalContent = this.getGlobalContent;
this.cartSummary = this.cartPerfs;
this.myHtml = this.myNewHtml;
}; //End $onInit
}
Main Controller
function subAppController($sce) {
this.$onInit = function () {
//Get content from Parent
this.globalContent = this.getGlobalContent;
}; //End $onInit
this.continueClick = function () {
console.log("Continue Selected");
};
this.currentStep = 1;
this.contentJson = pcContent;
this.globalContentJson = pcGlobalContent;
this.cartPerfs = pcCartPerfs
//Called from the template to get global content.
this.getGlobalContent = function (module, item) {
var globalContent = new contentProvider(this.globalContentJson);
var result = globalContent.get(module, item);
return result;
}
this.myNewHtml = function (item) {
var result = $sce.trustAsHtml(item);
return result;
}
//Get the current count of valid performance in the cart
// We use this to determine if we hide/disable the continue buttons.
this.min_perfs = this.contentJson.required_min_perfs;
this.curr_perf_count = this.cartPerfs.length;
this.continueActive = this.curr_perf_count >= this.min_perfs;
}
Main Template
<div class="container-fluid">
<!--Top (Bread crumbs and Cart Summary)-->
<div class="cs-app-top row">
<div class="cs-app-left col-sm-3">
<div class="pull-left">
<div class="bcrumbs">Step 1 > Step2</div>
<div>
<label class="cs-page-title">{{$ctrl.contentJson.page_title}}</label>
</div>
</div>
</div>
<div class="cs-app-right pull-right col-sm-9">
<cart-summary content-json="$ctrl.contentJson"
get-global-content="$ctrl.getGlobalContent(module,item)"
cart-perfs="$ctrl.cartPerfs"
my-new-html="$ctrl.myNewHtml(item)">
</cart-summary>
<div class="cs-continue-btn-div pull-right">
<button class="cs-continue-btn cs-btn"
ng-bind="$ctrl.globalContent('subpackage','continueBtnText')"
ng-class="{'hidden': !$ctrl.continueActive}"
ng-disabled="!$ctrl.continueActive"
ng-click="$ctrl.continueClick()" ></button>
</div>
</div>
</div>
<!--Header Content-->
<div class="cs-header row">
<div ng-bind-html="$ctrl.myNewHtml($ctrl.contentJson.page_header)"></div>
</div>
<!--Main Section (perf-list)-->
<div class="cs-app-main row">
<div>
<perf-list ng-if="$ctrl.currentStep == 1"
content-json="$ctrl.contentJson"
get-global-content="$ctrl.getGlobalContent(module,item)">
</perf-list>
</div>
</div>
<!--Footer-->
<div class="cs-app-footer row">
<div class="cs-continue-btn-div pull-right">
<button class="cs-continue-btn cs-btn"
ng-bind="$ctrl.globalContent('subpackage','continueBtnText')"
ng-disabled="!$ctrl.continueActive"
ng-click="$ctrl.continueClick()"></button>
</div>
</div>
</div>
--Module
var myApp = angular.module('subPackages', ['ngMaterial', 'ngMessages','ngSanitize']).config(function($sceDelegateProvider) {
$sceDelegateProvider.resourceUrlWhitelist([
// Allow same origin resource loads.
'self',
// Allow loading from our assets domain. Notice the difference between * and **.
'Protected content**'
]);
});
(function (app) {
'use strict';
app.component('appComponent', {
templateUrl: '../subpackages/templates/app-template.html',
controller: subAppController
});
app.component('cartSummary', {
templateUrl: '../subpackages/templates/cart-summary.template.html',
controller: cartSummaryController,
bindings: {
contentJson: '<',
cartPerfs: '<',
getGlobalContent: '&',
myNewHtml: '&'
},
});
app.component('perfList', {
templateUrl: '../subpackages/templates/perf-list.templateV3.html',
controller: PerfListController,
bindings: {
contentJson: '<',
getGlobalContent: '&'
},
});
})(myApp);

You could create a custom directive as show in Execute a function inside ng-repeat in AngularJS

Found the solution. Instead of doing this
<td class="cs-cart-sum-td" ng-bind="$ctrl.myNewHtml(cartperf.perf_desc)"></td>
I did this.
<td class="cs-cart-sum-td" ng-bind-html="$ctrl.myHtml({item: cartperf.perf_desc})"></td>

Related

Unable to use controller as syntax to set up directive (scope mismatch)

I am pulling my hair out trying to get a directive called webix-ui to assume the same scope level as parent scope. This code is the closest to making webix-ui work, but the element still sees childscope.
What am I doing wrong and why is my controller as not being picked up globally?
I am nearing the point of giving up as I have tried nearly 10-15 variations of my code, this one being the most promising and hopefully in the right direction.
I can provide additional details as necessary.
Module Controller
angular.module('Risk').controller('CreateRiskController', ['$http', '$resource', '$scope', '$state', '$window', '$timeout', '$interval', '$sce', 'CommonService', function($http, $resource, $scope, $state, $window, $timeout, $interval, $sce, CommonService){
refresh = false;
var vm = this;
vm.config = {}
vm.initDone = false;
vm.setup = {
done: false
}
vm.model = { elem: true }
vm.risk = {
risktitle: '',
riskstatement: '',
context: '',
closurecriteria: '',
likelihood:'',
technical:'',
schedule:'',
cost:''
};
vm.fields = [
'risktitle',
'riskstatement',
'context',
'closurecriteria',
'likelihood',
'technical',
'schedule',
'cost'
]
vm.risklevels = {
riskmaximum: '',
riskhigh: '',
riskmedium: '',
riskminimum: ''
}
vm.flags = {
disabled: true
}
vm.riskMatrix = [];
for(var l = 1; l <= 5; l++)
{
vm.riskMatrix[l] = [];
for (var c = 0; c <= 5; c++)
{
vm.riskMatrix[l][c] = '';
}
}
vm.riskLevel = function(l, c){
elem = document.querySelector("div[name='risk["+l+"]["+c+"]']");
risk = vm.riskMatrix[l][c];
if (risk == '')
return (elem && elem.hasAttribute('class'))?
elem.getAttribute('class') : '';
if (risk >= vm.risklevels.riskhigh)
return 'cell high';
else if (risk >= vm.risklevels.riskmedium && risk < vm.risklevels.riskhigh)
return 'cell med';
else if (risk < vm.risklevels.riskmedium)
return 'cell low';
}
vm.valid = function(){
return CommonService.riskFormValid(vm.fields, vm);
}
vm.invalidLevel = function(lvl){
return CommonService.invalidLevel(lvl);
}
$scope.$on("$destroy", function(){
formcheck = 0;
angular.element(document.querySelector('link[href="/app/tool/risk/CreateRisk.css"]')).remove();
});
vm.initRisk = function(data){
vm.risklevels.riskmaximum = data.Levels[0].riskmaximum;
vm.risklevels.riskhigh = data.Levels[0].riskhigh;
vm.risklevels.riskmedium = data.Levels[0].riskmedium;
vm.risklevels.riskminimum = data.Levels[0].riskminimum;
for (var idx = 0; idx < data.Thresholds.length; idx++)
{
var l = data.Thresholds[idx].likelihood;
var c = data.Thresholds[idx].consequence;
v = data.Thresholds[idx].level;
vm.riskMatrix[l][c] = v;
}
}
vm.init = function(){
return $http.get('/api/riskconfig').then(function(response){
if (response.data.Succeeded){
vm.initRisk(response.data.Result);
return response.data.Result;
}
else{
vm.msg = $sce.trustAsHtml(response.data);
}
});
}
vm.submit = function(){
if (!vm.valid())
vm.msg = "Please complete form and resubmit";
else{
//vm.actionitem.duedate = vm.split(vm.actionitem.duedate,'T')[0];
//vm.actionitem.ecd = vm.split(vm.actionitem.ecd, 'T')[0];
$http.post('/api/risks', vm.risk).then(function(response){
if (response.data.Succeeded){
vm.msg = response.data.Result;
}
else{
vm.msg = $sce.trustAsHtml(response.data);
}
});
}
}
}]);
Directive
angular.module('Risk').directive('config', ConfigElement);
function ConfigElement(){
var directive = {
restrict: 'A',
compile: function (){
return {
pre: function (scope, elem, attrs){
var vm = scope.vm;
vm.config[attrs.config] = {done: false}
},
post: ConfigController
}
},
controller: 'CreateRiskController',
controllerAs: 'vm',
bindToController: true,
scope: false
}
return directive;
}
function ConfigController(scope, element, attrs, DOMops, ValidationService){
//$scope.$watch('setup.done', function(dataReady,dataNotReady,scope){
// if (dataReady){
var vm = scope.vm;
var attr = attrs.config;
var type = attrs.type;
var width = attrs.width;
var height = attrs.height;
var maxlength = attrs.hasOwnProperty('maxlength')? attrs.maxlength: null;
var view;
if (type == "level")
view = "text";
else
view = type;
var config =
{
view: view,
value: vm.risk[attr],
on: {
"onTimedKeyPress": function(code){
var obj = this.eventSource || this;
ValidationService.handleKeyPress(obj, code, attr);
if (type == "level")
DOMops.assignRiskLevel(scope, obj);
},
"onBlur": function(code){
var obj = this.eventSource || this;
ValidationService.updateAndValidate(obj,code,attr);
}
},
responsive: true,
width: width,
height: height
};
if (maxlength)
config.attributes = {maxlength : maxlength};
config.done = true;
vm.config[attr] = config;
//$scope.$eval($attrs.onConfig, {$config: $scope.config[$attrs.name]});
// }
//});
}
Template
<div id="formcontainer" ng-app="Risk" ng-controller="CreateRiskController as vm" get-risk>
<div id="mycreateform" class="container" type="space" layout-padding="" ng-cloak="">
<form id="form" name="CreateRisk" role="form" ng-submit="vm.valid() && vm.submit()" novalidate>
<div id="details" class="layout" border="1">
<div class="tr">
<div class="td label">
Title
</div>
<div config="risktitle" class="td locked" width="500" height="30" type="text">
<div ng-if="vm.config.risktitle.done" ng-model="vm.config.risktitle" webix-ui="vm.config.risktitle" id="risktitle" name="risktitle"></div>
</div>
</div>
<div class="tr">
<div class="td label">
Risk Statement
</div>
<div config="riskstatement" class="td locked" width="500" height="97" type="textarea">
<div ng-if="vm.config.riskstatement.done" ng-model="vm.config.riskstatement" webix-ui="vm.config.riskstatement" id="riskstatement" name="riskstatement"></div>
</div>
</div>
<div class="tr">
<div class="td label">
Context
</div>
<div config="context" width="500" height="97" type="textarea" class="td locked">
<div ng-if="vm.conig.context.done" ng-model="vm.config.context" webix-ui="vm.config.context" id="context" name="context"></div>
</div>
</div>
<div class="tr">
<div class="td label">
Closure Criteria
</div>
<div config="closurecriteria" width="500" height="97" type="textarea" class="td locked">
<div ng-if="vm.config.closurecriteria.done" ng-model="vm.config.closurecriteria" webix-ui="vm.config.closurecriteria" id="closurecriteria" name="closurecriteria"></div>
</div>
</div>
<!--tr class="text">
<div class="td label">
Category
</div>
<div class="locked">
<div id="category" name="category" />
</div>
</div-->
</table>
<h2>Initial Risk Assessment</h2>
<div class="nested">
<div class="info">
<div id="details" class="table" border="1">
<div class="tr">
<div class="td label">
Likelihood
</div>
<div config="likelihood" width="30" height="30" maxlength="1" type="level" class="td locked">
{{config.likelihood}}<div ng-if="vm.config.likelihood.done" ng-model="vm.config.likelihood" webix-ui="vm.config.likelihood" id="likelihood" name="likelihood"></div>
</div>
</div>
<div class="tr">
<div class="td label" colspan="2">
Consequence
</div>
</div>
<div class="tr">
<div class="td label margin-left">
Technical
</div>
<div config="technical" width="30" height="30" type="level" maxlength="1" class="td locked">
{{config.technical}}<div ng-if="vm.config.technical.done" ng-model="vm.config.technical" webix-ui="vm.config.technical" id="technical" name="technical"></div>
</div>
</div>
<div class="tr">
<div class="td label margin-left">
Schedule
</div>
<div config="schedule" width="30" height="30" type="level" maxlength="1" class="td locked">
{{config.schedule}}<div ng-if="vm.config.webix" ng-model="vm.config.schedule" webix-ui="vm.config.schedule" id="schedule" name="schedule"></div>
</div>
</div>
<div class="tr">
<div class="td label margin-left">
Cost
</div>
<div config="cost" width="30" height="30" type="level" maxlength="1" class="td locked">
{{config.cost}}<div ng-if="vm.config.cost.done" ng-model="vm.config.cost" webix-ui="vm.config.cost" id="cost" name="cost"></div>
</div>
</div>
</div>
<div name="level"></div>
</div>
<div class="info" ng-if="vm.setup.done">
<table class="matrix" id="riskmatrix">
<tbody>
<tr ng-repeat="likelihood in [5,4,3,2,1]">
<td ng-if="likelihood == 2" class="vlabel">Likelihood</td>
<td ng-if="likelihood != 2"></td>
<td class="likelihood">{{likelihood}}</td>
<td ng-repeat="consequence in [1,2,3,4,5]" name="risk[{{likelihood}}][{{consequence}}]" ng-model="vm.riskMatrix[likelihood][consequence]" ng-class="[vm.riskLevel(likelihood,consequence)]"></td>
</tr>
<tr>
<td></td>
<td></td>
<td ng-repeat="consequence in [1,2,3,4,5]">{{consequence}}</td>
</tr>
<tr>
<td></td><td></td><td colspan="5">Consequence</td>
</tr>
</tbody></table>
</div>
</div>
<divider></divider>
<div class="tr">
<div class="tr">
<button id="submit" type="submit" disabled="disabled" class="raised primary">Create Risk</button>
</div>
</div>
<div class="tr">
<div class="msg" layout-align="center">
<span ng-bind-html="msg">{{msg}}</span>
</div>
</div>
</form>
</div>
</div>
Initializing my div directive with an object whose property was initially false and then using "as ctrl" in my template solved the issue finally. I had to use this in my controller and scope.ctrl.<property> in. It seems to have worked similar to the syntax as many references places suggesting use of this pointer instead of $scope.
The only thing that I changed was use of ng-show instead of ng-if. I have not used ng-if but I suspect it might still work too.
<div id="formcontainer" ng-app="Risk" ng-controller="CreateRiskController as ctrl" ng-cloak>
<get-risk></get-risk>
<div id="mycreateform" class="container" type="space" layout-padding="">
<form id="form" name="CreateRisk" role="form" ng-submit="ctrl.valid() && ctrl.submit()" novalidate>
<table id="details" class="layout" border="1">
<tr>
<td class="label">
Title
</td>
<td class="locked">
<div ng-show="ctrl.config.risktitle.done" config="risktitle" webix-ui="risktitle" width="500" height="30" type="text" id="risktitle" name="risktitle"></div>
</td>
</tr>
</table>
</form>
</div>
</div>
Directive
angular.module('Risk').directive('config', ConfigElement);
function ConfigElement(){
var directive = {
restrict: 'A',
link: linkFn,
controller: ConfigController
}
function linkFn(scope, elem, attrs){
var attr = attrs.config;
var type = attrs.type;
var width = attrs.width;
var height = attrs.height;
var maxlength = attrs.hasOwnProperty('maxlength')? attrs.maxlength: null;
var view;
if (type == "level")
view = "text";
else
view = type;
scope.ctrl.DOMops.setValidationServiceObj(scope.ctrl.ValidationService);
scope.ctrl.DOMops.setValue('risk', scope.ctrl.risk);
scope.ctrl.DOMops.setValue('riskMatrix', scope.ctrl.riskMatrix);
scope.ctrl.DOMops.setValue('risklevels', scope.ctrl.risklevels);
scope.ctrl.ValidationService.setValue('risk', scope.ctrl.risk);
scope.ctrl.ValidationService.setDOMobj(scope.ctrl.DOMops);
var config =
{
view: view,
value: scope.ctrl.risk[attr],
on: {
"onTimedKeyPress": function(){
var obj = this.eventSource || this;
code = this.getValue();
scope.ctrl.ValidationService.handleKeyPress(code, scope.ctrl, obj, attr);
if (type == "level")
scope.ctrl.DOMops.assignRiskLevel(obj);
},
"onBlur": function(){
var obj = this.eventSource || this;
code = this.getValue();
scope.ctrl.ValidationService.getTextValueAndValidate(code, scope.ctrl, obj, attr);
}
},
responsive: true,
width: width,
height: height
};
if (maxlength)
config.attributes = {maxlength : maxlength};
config.done = true;
scope.ctrl.config[attr] = config;
}
return directive;
}
function ConfigController($scope, $element, $attrs){
$scope.ctrl.config[$attrs.config] = {done: false};
}

Angularjs cannot perform crud operations from accordion

I am trying to add a form to a bootstrap accordion and post a text value. Without accordion the form works alright. When i added the form to the accordion i am not able to pass text box value to angularjs controller. Basically i am not able to perform the CRUD operations as i am not able to pass the values. Minimum code related to the issue.
main.html
<div ng-controller="myController">
<accordion class="accordion" close-others="oneAtATime">
<accordion-group ng-repeat="group in groups" is-open="status.isOpen[$index]" >
<accordion-heading>
{{group.groupTitle}} <i class="fa chevron-icon" ng-class="{'fa-chevron-down': status.isOpen[$index], 'fa-chevron-right': !status.isOpen[$index]}"></i>
</accordion-heading>
<div ng-include="group.templateUrl"></div>
</accordion-group>
</accordion>
</div>
controller.js
App.controller('myController', ['$scope', 'Parts', function($scope, Parts) {
var original = $scope.parts;
$scope.submit = function() {
if ($scope.parts.a_id == null) {
$scope.createNewPart();
} else {
$scope.updatePart();
}
};
$scope.createNewPart = function() {
Parts.resource1.create($scope.parts);
};
$scope.updatePart = function() {
Parts.resource2.update($scope.parts)
};
$scope.oneAtATime = true;
$scope.groups = [{
groupTitle: "ADD 1",
templateUrl: "file1.html"
}, {
groupTitle: "ADD 2",
templateUrl: "file2.html"
}];
$scope.status = {
isOpen: new Array($scope.groups.length)
};
for (var i = 0; i < $scope.status.isOpen.length; i++) {
$scope.status.isOpen[i] = (i === 0);
}
} ]);
file1.html
<div>
<form name="myForm" ng-submit="submit()">
<div class="row">
<label class="col-md-2 control-lable" for="part">Add1</label>
<input type="text" ng-model="parts.part" id="part" required />
</div>
<div class="row">
<input type="submit" value="{{!parts.id ? 'Add' : 'Update'}}" ng-disabled="myForm.$invalid">
</div>
</form>
//inside table
<tr ng-repeat="a in availableparts >
<td>{{a.id}}</td>
<td>{{a.apart}}</td>
<td><button type="button" ng-click="editPart(a.id)" >Edit</button>
<button type="button" ng-click="deletePart(a.id)">Remove</button>
</td>
</tr>
</div>
Initially, you need to set $scope.parts to empty object {}, so when you access $scope.parts.id you will have null, instead of error saying id of undefined

Linking one controller to another to call service on ng-click

I have two templates with respective controllers and service files. One template's(fleetListTemplate) controller(fleetListController) loads data from its service file(fleetService) and displays in its view(fleetListTemplate).
When this happens, and I click on one of the loaded data from fleetService, I should link fleetListController to fleetSummaryController to get data from its service file (fleetSummaryService) and display in fleetSummaryTemplate view.
Can someone please help me with the coding? Thank you.
The following are the respective modules, templates, controllers and service files.
fleetListModule
"use strict";
angular.module("fleetListModule", []);
fleetListTemplate
<div class="panel1 panel-primary">
<div class="panel-heading" align="center">TRUCKS</div>
<table class="table table-bordered table-condensed table-striped">
<tr>
<th>TruckID</th>
<th>Status</th>
<th>Dest.</th>
<th>Alerts</th>
</tr>
<tr ng-repeat="truck in trucks" ng-click="summaryData()">
<td>{{truck.truckID}}</td>
<td>{{truck.status}}</td>
<td>{{truck.destination}}</td>
<td>{{truck.alerts}}</td>
</tr>
</table>
</div>
fleetListController
"use strict";
angular.module("fleetListModule").controller("fleetListController",
['$scope', 'fleetsService',
function ($scope, fleetsService) {
$scope.trucks = fleetsService.getTrucks();
$scope.summaryData = function () {
$rootScope.$broadcast('obtainSummary');
}
}]);
fleetSummaryModule
"use strict";
angular.module("fleetSummaryModule", []);
fleetSummaryTemplate
<div class="panel2 panel-primary">
<div class="panel-heading">Summary</div>
<table class="table table-bordered table-condensed table-striped">
<tr ng-repeat="summary in truckSummary">
<td>Truck ID: {{summary.truckID}}</td>
<td>Trailer ID: {{summary.trailerID}}</td>
<td>Driver ID: {{summary.driverID}}</td>
<td>Truck Number: {{summary.truckNumber}}</td>
<td>Trailer Number: {{summary.trailerNumber}}</td>
<td>Insurance Due Date: {{summary.insuranceDueDate}}</td>
<td>Maintenance Due Date: {{summary.maintenanceDueDate}}</td>
</tr>
</table>
</div>
fleetSummaryController
"use strict";
angular.module("fleetSummaryModule").controller("fleetSummaryController",
['$scope', 'fleetSummaryService',
function ($scope, fleetSummaryService) {
$scope.$on('obtainSummary', function (event, args) {
$scope.truckSummary = fleetSummaryService.getSummary();
})
}]);
fleetSummaryService
"use strict";
angular.module("fleetSummaryModule").service("fleetSummaryService",
function () {
this.getSummary = function () {
return summary;
};
this.getSummary = function (truckID) {
for (var i = 0, len = truckSummary.length; i < len; i++) {
if (truckSummary[i].truckID === parseInt(truckID)) {
return truckSummary[i];
}
}
return {};
};
var truckSummary = [
{
truckID: 1,
trailerID: '123',
driverID: 'Alex123',
truckNumber: 'hyt 583',
trailerNumber: 'xyz213',
insuranceDueDate: '25-12-2015',
maintenanceDueDate: '31-12-2015'
},
{
truckID: 2,
trailerID: '456',
driverID: 'Alex123',
truckNumber: 'hyt 583',
trailerNumber: 'xyz213',
insuranceDueDate: '25-12-2015',
maintenanceDueDate: '31-12-2015'
},
{
truckID: 3,
trailerID: '789',
driverID: 'Alex123',
truckNumber: 'hyt 583',
trailerNumber: 'xyz213',
insuranceDueDate: '25-12-2015',
maintenanceDueDate: '31-12-2015'
}
];
});
This simple example show to you how to share data between 2 controllers "in one app"
using common service.
angular.module("app", []);
///controller1
angular.module("app").controller("controller1", function ($scope, service) {
$scope.lists = [
{ name: "maher" },
{ name: "Gaurav Ram" },
{ name: "Shaun Scovil" }
];
$scope.send = function () {
service.set("lists", $scope.lists); //set(key, value)
$scope.lists = []; //optional
}
});
///controller2
angular.module("app").controller("controller2", function ($scope, service) {
$scope.lists = [];
//get data from broadcast on the root
service.get("lists"); // get(key)
//set data
$scope.resive = function () {
if (angular.isUndefined($scope.broadcast)) {
$scope.alert = "No data to resive!";
} else {
$scope.alert = null;
$scope.lists = $scope.broadcast;
}
}
});
///service
angular.module("app").service("service", function ($rootScope) {
this.set = function (key, value) {
$rootScope.$broadcast(key, value);
}
this.get = function (key) {
$rootScope.$on(key, function (event, data) {
$rootScope.broadcast = data;
});
}
});
<!doctype html>
<html ng-app="app">
<head>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" />
</head>
<body>
<div ng-controller="controller1" class="col-md-6 col-sm-6 col-xs-6">
<div class="page-header">
<h1>controller 1</h1>
</div>
<button ng-click="send()" class="btn btn-primary">Send</button>
<div class="clearfix"></div>
<br/>
<div class="alert alert-info" ng-if="lists.length == 0">Data <b>sent</b> to controller 2, click Resive button to get data</div>
<ul class="list-group">
<li ng-repeat="list in lists" class="list-group-item" ng-bind="list.name"></li>
</ul>
</div>
<div ng-controller="controller2" class="col-md-6 col-sm-6 col-xs-6">
<div class="page-header">
<h1>controller 2</h1>
</div>
<button ng-click="resive()" class="btn btn-success">Resive</button>
<div class="clearfix"></div>
<br />
<div class="alert alert-info" ng-bind="alert" ng-if="alert"></div>
<ul class="list-group">
<li ng-repeat="list in lists" class="list-group-item" ng-bind="list.name"></li>
</ul>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.8/angular.min.js"></script>
</body>
</html>

Error "cannot set property gridDim of undefined" in angular js

Getting error "cannot set property gridDim of undefined" while using ng-grid in angular js. i have already declared vm.gridOptions = { data: 'vm.course_view'};.plz help me
<section class="mainbar">
<section class="matter">
<div class="container">
<div class="row" ng-controller="Course_view">
<div class="col-lg-5 col-lg-offset-2">
<div class="widget wblue">
<div vis-widget-header title="{{vm.title}}"></div>
<div class="widget-content user">
<!-- <table data-toggle="table" data-height="150" class="table table-condensed table-hover">
<thead>
<tr>
<th>Lesson</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="c in vm.course_view"
>
<td>{{c.firstName}}</td>
</tr>
</tbody>
</table> -->
<div class="gridStyle" ng-grid="course_view"></div>
</div>
<div class="widget-foot">
<div class="clearfix"></div>
</div>
</div>
</div>
</div>
</div>
</section>
Here is Code for controller
(function() {
'use strict';
angular
.module('app.course_view')
.controller('Course_view', Course_view);
/* #ngInject */
function Course_view($state, dataservice, logger) {
var vm = this;
vm.course_view = [];
vm.title = 'Course_view';
vm.gridOptions = { data: 'vm.course_view', columnDefs: [
{field:'firstName', displayName:'firstName'}
]};
activate();
function activate() {
return getCourse_View().then(function() {
logger.info('Activated course_view View');
});
}
function getCourse_View() {
return dataservice.getCourse_View().then(function(data) {
vm.course_view = data;
debugger;
return vm.course_view;
});
}
}
})();
Please, try to change the following code:
<div class="row" ng-controller="Course_view">
on
<div class="row" ng-controller="Course_view as courseCtrl">
and
<div class="gridStyle" ng-grid="course_view"></div>
on
<div class="gridStyle" ng-grid="courseCtrl.course_view"></div>
And please, give me feedback about your success/fail in comments.
UPDATE:
I've created JSFiddle for you with working example.
I'm a little bit simplified example, but it should work.
<div ng-controller="CourseViewCtrl as ctrl">
<div class="gridStyle" ng-grid="ctrl.gridOptions"></div>
</div>
(function() {
'use strict';
var myApp = angular.module('myApp',['ngGrid']);
myApp.controller('CourseViewCtrl', CourseViewCtrl);
function CourseViewCtrl($http) {
var vm = this;
vm.course_view = [];
vm.gridOptions = {
data: 'ctrl.course_view'
};
activate();
function activate() {
return $http.get("/data").success(function(data) {
vm.course_view = data;
});
};
}
})();
I want to note on main differences between your code:
Grid options in the controller:
vm.course_view = [];
vm.gridOptions = {
data: 'ctrl.course_view'
};
Grid on the view:
<div class="gridStyle" ng-grid="ctrl.gridOptions"></div>

Why are changes in my arrays in my controller not being reflected in my view?

This is branching off of my last question: How to call $scope.$apply() using “controller as” syntax
I am using TypeScript in conjunction with Angular
Problem: I have an ng-repeat in my view
<!-- Simple View -->
<div ng-hide="wordTrack.showDetailedView">
<div class="col-md-12" id="wordTrackResult" style="padding: 10px; overflow-y: auto; overflow-x: hidden;">
<div class="wordListWellWrapper row" ng-repeat="words in wordTrack.wordList">
<div class="col-md-5 wordListWell form-control" ng-class="(words.IsPositive)? 'posWordWell': 'negWordWell' ">
<strong class="wordListWord">{{words.Word}}</strong>
<div class="wordListIcon">
<div class="whiteFaceIcon" ng-class="(words.IsPositive)? 'happyWhiteIcon': 'sadWhiteIcon' "></div>
</div>
</div>
<div class="col-md-2">
<span aria-hidden="true" class="glyphicon-remove glyphicon" ng-click="wordTrack.removeWord(words.Word)"></span>
</div>
</div>
<p class="noWordText" ng-show="(wordTrack.notUsedWordList.length > 0)">The following words have not yet been used</p>
<div class="wordListWellWrapper row" ng-repeat="words in wordTrack.notUsedWordList">
<div class="col-md-5 wordListWell form-control" style="background-color: gray;">
<strong class="wordListWord">{{words}}</strong>
</div>
<div class="col-md-2">
<span aria-hidden="true" class=" glyphicon-remove glyphicon" ng-click="wordTrack.removeWord(words)"></span>
</div>
</div>
</div>
</div>
which is using two arrays in my controller (wordList and notUsedWordList):
module WordsToTrackController {
export class Controller {
public static $inject = ["$scope", "CampaignFactory", "VideoFactory", "DashboardFactory", "WordsToTrackFactory"];
wordList: Array<IWordTrackItem>;
notUsedWordList: Array<string>;
constructor($scope: ng.IScope, campaignFactory, videoFactory, dashboardFactory, wordsToTrackFactory) {
this.campaignFactory = campaignFactory;
this.videoFactory = videoFactory;
this.dashboardFactory = dashboardFactory;
this.wordsToTrackFactory = wordsToTrackFactory;
this.wordList = [];
this.notUsedWordList = [];
this.hasData = false;
this.fetchInProgress = false;
$scope.$on("video-switch",() => {
this.setWordLists();
});
$scope.$on("detail-switch",() => {
this.showDetailedView = this.dashboardFactory.isDetailedView;
});
}}}
Inside my constructor, I am calling
$scope.$on("video-switch",() => {
this.setWordLists();
});
which executes setWordLists() which attempts to grab the data from one of my factories and set the values of the arrays (which it is doing correctly)
Controller:
setWordLists() {
this.fetchInProgress = true;
var campaignId = this.campaignFactory.currentId();
var videoId = this.videoFactory.currentId();
if (!campaignId || !videoId) {
return;
}
this.wordsToTrackFactory.doGetWordsToTrackModel(campaignId, videoId)
.then((response) => {
this.fetchInProgress = false;
this.wordList = (response) ? response.data.WordList : [];
this.notUsedWordList = (response) ? response.data.NotUsedWords : [];
});
}
Factory:
function doGetWordsToTrackModel(campaignId: number, videoId: number) {
return $http
.get(url, {
params: {
videoId: videoId,
campaignId: campaignId
}
});
}
Now, the problem is that even though the arrays are being set to the correct values, it is not being updated in my view (inside the ng-repeat).
I don't want to call $scope.$apply() for a quick fix either. Can anyone spot the source of the problem?
Edit:
$scope.$apply() doesn't help, so i'm thinking ng-repeat isn't binding correctly, but I can't see how I set the view up incorrectly.
Edit: ........
I'm a moron and put my ' ng-controller="Controller as controller" ' on the incorrect element.......
wrong code:
<div class="col-md-4" >
<h2 class="text-center" ng-controller="WordsToTrackController as wordTrack">Words to Track</h2>
corrected code:
<div class="col-md-4" ng-controller="WordsToTrackController as wordTrack">
<h2 class="text-center">Words to Track</h2>

Resources