Angular - 2 dependent menus binding - angularjs

I build a ASP.Net MVC 4 + angular website,
I have an upper menu, while a click on one link will open the left menu links accordingly.
suppose you click the first category (1) upper menu, the left menu will be exposed accordingly 1.1, 1.2, 1.3.
Currently, my upper menu is binded, but when clicking on a link (category), nothing happens on the left menu.
if i put alert, i see the data comes back to the client. it is not a data problem.
any idea guys ? :-)
my index.html to contain the 2 partials:
<html>
<head>
<script src="Scripts/angular.min.js"></script>
<script src="app/controllers/menuController.js"></script>
<title></title>
</head>
<body ng-app="generalApp">
<div ng-include="'partials/topMenu.html'"></div>
<div ng-include="'partials/sideMenu.html'"></div>
</body>
</html>
my upper menu (different html file - working):
<div ng-controller="menuController">
<table>
<tr ng-repeat="category in menuCategories">
<td>
<a href="#" ng-click="loadSideMenu('7')">
{{category.CategoryName}}
</a>
</td>
</tr>
</table>
</div>
my side menu (different html file):
<div ng-controller="menuController">
<table>
<tr ng-repeat="category in sideMenu">
<td>{{ category.CategoryName }}</td>
</tr>
</table>
</div>
my js controller code:
(function (angular) {
var generalApp = angular.module('generalApp', [])
.controller('menuController', function ($scope, $http) {
$http.post("Home/GetArticleCategories").then(function (response) {
$scope.menuCategories = response.data;
});
$scope.loadSideMenu = function(category) {
$http.post("Home/GetSideMenu?a="+category).then(function (response) {
$scope.sideMenu = response.data;
});
};
});
}(angular));
my mvc controller to return the faked links upon the category click :
public JsonResult GetSideMenu(int a)
{
var j = Json(new[]{
new { CategoryName = "link 1"},
new { CategoryName = "link 2"}
}
);
return j;
}
Thanks to any idea !!!

You must put upper and left menus inside the same ng-contoller. The way you did every div will have a different $scope. When you populate the data in the upper menu, the $scope from the upper menu will hold the list, and the left will not notice that, because they have different $scopes.
Think as they are the same kind of object, but different instances!

Related

Angularjs: ng-model not displaying properly

I have a parent and child controller relationship. This is a non-working mockup of the basic functionality. I'm sure anyone more competent than me can get it working for a Plunker or Fiddle model. (So there is probably something wrong with: $scope.data.contactList = [{ID: 1, Email: "someemail#email.com"}, {ID: 2, Email: "anotheremail#email.com"}];) I tried creating some objects for the contactList array.
Anyway. I want to be able to click a link in the second table in the code below to invoke EditShowContact. In my actual app, this will show a hidden div and it will obviously display more properties of a contact than just the email.
In my actual program, the values of the table are filled out properly (i.e. my ng-repeat directive is working fine), but I cant seem to get the ng-model directive to respond. I've tried various different ways and nothing seems to work.
<html ng-app="myApp"><head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular.min.js"></script>
<script>
var app = angular.module('myApp', []);
app.controller('ContactsController', function ($scope)
{
this.currentContactID = null;
this.EditShowContact = function(intContactID)
{
this.currentContactID = intContactID;
//this.currentContact = $scope.data.contactList[intContactID]; unclear why this assignment fails
};
});
app.controller('ActionsController', function ($scope)
{ $scope.data = {};
$scope.data.contactList = [{ID: 1, Email: "someemail#email.com"}, {ID: 2, Email: "anotheremail#email.com"}];
});
</script>
</head>
<body ng-controller="ActionsController as ActCtrl">
<div ng-controller="ContactsController as ContactsCtrl">
<table border = "1";>
<tr><th>Email</a></th>
<th>Name</th></tr>
</table>
<div >
<table ng-repeat="Contact in ContactsCtrl.data.contactList" border="1">
<tr>
<td>{{Contact.Email}}</td>
<td>{{Contact.Name}}</td>
</tr>
</table>
</div>
<div>
<form>
<input type="input" ng-model="ContactsCtrl.data.contactList[currentContactID].Email"></input>
</form>
</div>
</div>
</body>
</html>
There are quite a few errors here such as :
ContactsCtrl has no information about the ContactList. You are trying to find object in array using ID in place in index using <table> element inside <div> and more..
Bascially, i have reduced the need of two controllers to one and made a Working Demo.

Route to AngularJS Page with :id parameter

I have an AngularJS Application which uses ngRoute to handle the routing of the app. The routing itself is working (the URL is being redirected to the correct page and the correct partial is open) however, I cannot retrieve the item which I need in the second page.
The first page lets you search for a list of documents (dummy at the moment but will eventually link to an API). The list items are clickable and will route you to the second page where the details of the document are listed.
I will outline the way I am attempting to achieve this at the moment but I am open to suggestions if anyone has ideas about how this solution can be improved.
app.js
angular.module("app", ["ngRoute", "ngAnimate"])
.config(function($routeProvider){
$routeProvider
.when("/main", {
templateUrl: "Views/main.html",
controller: "MainController"
})
.when("/document/:id", {
templateUrl: "Views/document.html",
controller: "DocumentController"
})
.otherwise({redirectTo: "/main"});
});
main.html
<link rel="stylesheet" href="Stylesheets/main.css" type="text/css">
<div id="docSearchPanel" class="col-xs-12">
<ng-include src="'Views/Partials/documentSearchForm.html'"></ng-include>
</div>
<div id="formSearchResultsArea">
<div id="documentsFoundHeader">Documents Found</div>
<div id="documentsTableContainer">
<table id="documentsTable" class="table">
<thead>
<tr>
<th>ID</th>
<th>Title</th>
<th>Status</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="doc in documents" ng-click="showDocument()">
<td>{{doc.documentID}}</td>
<td>{{doc.documentTitle}}</td>
<td>{{doc.documentStatus}}</td>
</tr>
</tbody>
</table>
</div>
</div>
main.ctrl.js
angular.module("app").controller("MainController", function($scope, $location){
//This is populated by a function I have removed to keep the code simple
$scope.documents = []
$scope.showDocument = function(){
$scope.activeDocument = this.doc;
$location.path("document/"+this.doc.documentID);
};
});
document.html
<form ng-submit="downloadForm()" class="col-xs-12 col-md-6">
<h2>Document Details</h2>
<div class="row">
<h3>{{activeDocument.documentTitle}}</h3>
</div>
<div class="row" ng-repeat="field in selected.fields">
<div class="form-group">
<div class="document-attribute-header col-xs-5">{{field.key}}</div>
<div class="document-attribute-value col-xs-7">{{field.val}}</div>
</div>
</div>
</form>
document.ctrl.js
angular.module("app").controller("DocumentController", function($scope, $location, $routeParams){
$scope.activeDocument = getActiveDocument($routeParams.id);
function getActiveDocument(id){
for (var d in $scope.documents){
var doc = $scope.documents[d];
if (doc.documentID == id)
return doc;
}
}
});
The $scope-objects in the two controllers are not the same. You either make "documents" a member of the $rootScope (which you would need to inject in both controllers) or you make a documents-service which you inject.
Hope, that helped.

angular ng-click add http data inside ng-repeat

I use $http.get php data in ng-repeat is correct,but I have a problem when ng-click to add push php second page data in ng-repeat ,but it not work .
Any suggestions ? thanks.
I did not write very clear , i mean when click button , i want get ats01.php?page=2 data, add ats01.php?page=1 data in li ng-repeat, i don't want get page2 data replace page1 data,just like jquery $('#ul01').append (html) method; thank your answer it .
script.js
var scotchApp = angular.module('scotchApp');
var myurl="http://192.168.5.9/"
scotchApp.controller('mainController', function($scope, $http) {
$http.get(myurl+"php/ats01.php?page=1")
.success(function (response) {$scope.names = response.records;});
$scope.myur=myurl;
$scope.add = function() {
$http.get(myurl+"php/ats01.php?page=2")
.success(function (response) {
$scope.names.push(response.records);
});
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<html >
<head >
<script src="anjs/angular.min.js"></script>
<script src="script.js"></script>
</head>
<body ng-app="scotchApp" >
<div ng-controller="mainController">
<ul >
<li ng-repeat="x in names track by $index">
<p > <small>{{x.TA002}} {{x.TA003}} {{x.TA004}} {{x.TA012}}</small> </p>
</li>
</ul>
<p> <button ng-click="add()">Add</button> </p>
</div>
</body>
</html>
For first time you are assigning record in the list
$scope.names = response.records;
But in click you are pushing same data instead of assigning
$scope.names.push(response.records);
If you push instead of assign it'll create a index and push whole data into that index.
Convert this
$scope.names.push(response.records);
to this
$scope.names=$scope.names.concat(response.records);

How to refresh the previous page using AngularJS?

We have ASP.NET application where we use AngularJS. There's a page with the table (list) that contains pictures and their properties. The pictures are in first column of the table. The code looks as following:
<td>
<a ng-href="{{pic.FullUrl}}" target="_blank">
<img class="img-thumbnail" ng-src="{{pic.FullUrl}}" alt="{{pic.AltText}}" />
</a>
</td>
We can edit some picture by clicking "Edit" button and go to the next page (edit). After we made the changes, we click "Back" button to return to the previous page (list).
The issue is the image on first page hasn't been refreshed if we changed it on edit page, that is pic.FullUrl doesn't take effect.
I've tried to use the watch function, but no luck.
How to make it work?
UPDATE
We have a service:
PictureApp.factory('PictureService', function ($http, $location) {
var PictureService = function () {
this.ToList = function (objType, objId, mode) {
$location.path('/' + objType + '/' + objId + '/' + mode);
};
And we use it when accept changes on edit page in this way:
$scope.Accept = function () {
...
query.then(function () {
PictureService.ToList($routeParams.objType, $routeParams.objId, $routeParams.mode);
});
};
As you can see we call ToList and go to list page, but without reloading.
In list's controller we have this:
$scope.$watch('rbMode', function (val) {
PictureService.ToList($routeParams.objType, $routeParams.objId, val);
});
On list page we have this:
<div ng-if="dataLoaded">
<div ng-switch="rbMode">
<div ng-switch-when="static">
<div ng-include="'partials/Pic/PicTable.htm'" onload="this.pics = data;"></div>
</div>
<div ng-switch-when="banner">
<accordion close-others="false">
<accordion-group is-open="expandBanners" heading="{{pics[0].TypeDescription}}" ng-repeat="pics in data">
<div ng-include="'partials/Pic/PicTable.htm'" onload="this.pics = $parent.pics;" ></div>
</accordion-group>
</accordion>
</div>
</div>
</div>
And PicTable.htm looks as following:
<tr ng-repeat="pic in pics" ng-class="{'movable-row':isBanner}">
<td>{{pic.PictureLinkID}}</td>
<td>
<a ng-href="{{pic.FullUrl}}" target="_blank">
<img class="img-thumbnail" ng-src="{{pic.FullUrl}}" alt="{{pic.AltText}}" tooltip-popup-delay='1000' tooltip-placement="right" tooltip="Кликните, чтобы открыть в полном размере" />
</a>
</td>
Sounds like you have an image cache issue. Place a timestamp parameter on the end of your image url "*.jpg?ts=3324324". This will let the browser know it needs to refetch the image once it has been edited. Initialize the timestamp when the page loads and update the timestamp whenever an image is edited.
You can try the plnkr below which you can observe in your network panel, will fetch the image each time the timestamp is updated.
Edit: updated to demonstrate communication across controllers.
http://plnkr.co/edit/lp9lwkR3hgsqtIt4c3N0?p=preview
<!DOCTYPE html>
<html>
<head>
<script data-require="angular.js#*" data-semver="1.4.0-rc.1" src="https://code.angularjs.org/1.4.0-rc.1/angular.js"></script>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div ng-controller="cntrl">
<img ng-src="{{imgurl}}'?ts={{lastEdit}}" />
</div>
<div ng-controller="editCntrl">
<button ng-click="updateTS()">Update ts</button>
</div>
<script>
var app = angular.module("app",[]);
app.controller("cntrl",function($scope){
$scope.lastEdit = (new Date()).getTime();
$scope.imgurl = "http://dummyimage.com/600x400/000/fff";
$scope.$on("edited",function(){
$scope.lastEdit = (new Date()).getTime();
});
});
app.controller("editCntrl",function($scope,$rootScope){
$scope.updateTS = function(){
$rootScope.$broadcast("edited");
}
});
angular.bootstrap(document,["app"]);
</script>
</body>
</html>
You can add time stamp to uniquely identify image url on change.
on edit add the time stamp like this...
pic.FullUrl = "...path/pic.jpg"+ "?ts=" +new Date();
this will tell the browser that your image had been changed and it will do refresh.

My carousel not working only when i am using ng-include. else its working

var AccordionApp = angular.module("Carouselapp", ['ui.bootstrap']);
function CarouselDemoCtrl($scope) {
$scope.myInterval = 50000;
$scope.slides = [
{ image1: 'IMAGES/AngularJS.jpg', image2: 'IMAGES/BigData.jpg' },
{ image1: 'IMAGES/Mainframe.png', image2: 'IMAGES/DOTNET.png' },
{ image1: 'IMAGES/AngularJS.jpg', image2: 'IMAGES/BigData.jpg' },
{ image1: 'IMAGES/Mainframe.png', image2: 'IMAGES/DOTNET.png' }
];
}
<!Doctype html />
<head>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.5/angular.js"></script>
<script src="Scripts/ui-bootstrap-tpls.min.js"></script>
<script src="example.js"></script>
<link href="CSS/bootstrap-combined.min.css" rel="stylesheet">
</head>
<body>
<div >
<carousel interval="myInterval">
<slide ng-repeat="slide in slides" active="slide.active">
<table>
<tr>
<td>
<img ng-src="{{slide.image1}}" style="margin:auto;">
</td>
<td><img ng-src="{{slide.image2}}" style="margin:auto;">
</td>
</tr>
</table>
</slide>
</carousel>
</div>
</body>
</html>
Hi,
My carousel using bootstrap is working fine when i am using a seperate page for it. but when i am including it in my index page its not working. I feel all my slides are active thats why its showing all the images.
Pls let me know how to solve this. I have spent 2 days on this already.
Thanks
The below snippet is working but when i using ng-include in div> tag and plave this in another html it stops working..
Pls help
I face the same issue and spend around 3 hours to get the correct answer.
Just add following line in your controller after loading you data in your controller:
$('#carousel').carousel('cycle');
Here is my working code:
Service.GetData('home').then(function (response) {
$scope.data = response.data.Data;
$('#carousel').carousel('cycle');
}, function (error) {
$scope.error = error.message;
});
I think you got the same problem than that guy : Directives inside ng-include
The ng-include create a new scope.
You can try to write :
$scope.myInterval = {value: 50000};
and use
<carousel interval="myInterval.value">
as a fix, because object and primitive inheritance dont work the same way.
Directive and scope inheritance are quite complicated, you can check the answer above for detail

Resources