This is a bit of a educational post.
I am trying to understand why my plunker here does not work. I simply want to connect facotry to controller, and then use ng-repeat to import data.
I have tried several syntax but cannot write proper implementation.
Tahnks for you help.
controller:
var wmapp = angular.module('wmapp' []);
.controller('restaurantlistController', function ($scope, $rootScope, restaurantsFactory) {
"use strict";
$scope.restaurantList = restaurantsFactory.getRestaurants(); //call to restaurantfactory
})
factory :
angular.module('wmapp.factory_restaurants', [])
.factory('restaurantsFactory', function () {
"use strict";
var factory = {
Restaurants : [
{Name: 'A La Biche Au Bois', venueType: 'Restaurant ', subCuisine: 'Italian', subsubCuisine: 'Classic/traditional', address: '45 Avenue Ledru-Rollin', cp: '75012', city: 'Paris', country: 'France', countryCode: 'FR', itemid: 'PARIREST002', phoneNumber: '+331 43 43 34 38', website: '', lat: 48.8482040, long: 2.3706140, icon: 'img/restaurant_pointer_WMcustom_40x49_v3.png'},
{Name: 'Allard ', venueType: 'Restaurant ', subCuisine: 'French', subsubCuisine: 'Classic/traditional', address: '41, rue Saint-André des Arts', cp: '75006', city: 'Paris', country: 'France', countryCode: 'FR', itemid: 'PARIREST004', phoneNumber: '+33158002342', website: 'http://www.restaurant-allard.fr/en', lat: 48.8532490, long: 2.3409810, icon: 'img/restaurant_pointer_WMcustom_40x49_v3.png'},
{Name: 'Ambassade d\'Auvergne', venueType: 'Restaurant ', subCuisine: 'French', subsubCuisine: 'Auvergne region', address: '22 Rue du Grenier Saint-Lazare', cp: '75003', city: 'Paris', country: 'France', countryCode: 'FR', itemid: 'PARIREST005', phoneNumber: '+331 42 72 31 22', website: 'http://www.ambassade-auvergne.com/', lat: 48.8631310, long: 2.3534140, icon: 'img/restaurant_pointer_WMcustom_40x49_v3.png'}
// more restaurans
],
getRestaurants : function () {
return factory.Restaurants;
},
};
return factory;
});
html:
<div data-ng-controller="restaurantlistController" ng-repeat="restaurant in restaurantList " href="#">
<article class="item_frame">
<div class="marker_left_container">
<img class="venue_rest_marker" ng-src="{{restaurant.icon}}" />
<span class="venu_type_text">{{restaurant.venueType}}</span>
<span class="distance_from_user_rest">0.7 km</span>
<span class="distance_from_user_rest2">from current location</span>
</div>
<div class="restaurant_details_container">
<h1 class="restaurant_name_inlist">{{restaurant.Name}}</h1>
<span class="restaurant_detail_inlist2">{{restaurant.subCuisine}} <br />
{{restaurant.subsubCuisine}}</span>
<span class="restaurant_address">{{restaurant.address}}, <br />
</span>
<span class="restaurant_address">{{restaurant.cp}}, {{restaurant.city}} <br />
<br />
</span>
<span class="restaurant_others">{{restaurant.phoneNumber}} <br />
</span>
<span class="restaurant_others">{{restaurant.website}} <br />
<br />
</span>
</div>
</article>
<!--main article frame 1 -->
</div>
there more then 4 errors mainly semicolon , dots , module not include errors
check this link it is working now plunker
Related
I'm trying to teach myself Knockout.js by making a simple list of games one can add and remove from. At the moment I'm stuck on removing a specific item from an observable array. I have an array of games, and I have it foreach bound to a div that lists out the title, genre, platform, etc. for each game. I also have a Remove button for each game, but they don't work. I have it set up exactly like it is in Knockout's documentation here:
https://knockoutjs.com/documentation/click-binding.html
I also found someone else with the exact same problem here:
Remove items from Knockout observable array
However, the splice solution listed did not work for me. The function did fire this time, but instead of removing the correct item from the array, it removed the last item in the array, regardless of which Remove button was clicked. I'm at a loss as to why the code from Knockout's documentation doesn't work, and why the splice solution isn't working correctly. Here is my code. Pardon all the hard coded values. I'm just trying to get the basics of it working at the moment.
#{
ViewBag.Title = "My Game List";
}
<head>
<script type="text/javascript">
$(function () {
var game1 = ko.observable({
title: 'Bioshock',
genre: 'Shooter',
platform: 'XBox 360',
releaseDate: '8/21/2007',
developer: 'Irrational Games',
publisher: '2K Games',
imageURL: 'https://upload.wikimedia.org/wikipedia/en/thumb/6/6d/BioShock_cover.jpg/220px-BioShock_cover.jpg'
});
var game2 = ko.observable({
title: 'The Legend of Zelda: Ocarina of Time',
genre: 'RPG',
platform: 'N64',
releaseDate: '11/21/1998',
developer: 'Nintendo',
publisher: 'Nintendo',
imageURL: 'https://cdn-images-1.medium.com/max/1600/1*n2iccNMASW983gg-ZmMdTw.jpeg'
});
var game3 = ko.observable({
title: 'Devil May Cry',
genre: 'Hack-n-Slash',
platform: 'PS2',
releaseDate: '8/23/2001',
developer: 'Capcom',
publisher: 'Capcom',
imageURL: 'https://upload.wikimedia.org/wikipedia/en/thumb/1/1e/DMC1FrontCover.jpg/220px-DMC1FrontCover.jpg'
});
var game4 = ko.observable({
title: 'Comix Zone',
genre: 'Beat-em-Up',
platform: 'Sega Genesis',
releaseDate: '8/2/1995',
developer: 'Sega',
publisher: 'Sega',
imageURL: 'https://upload.wikimedia.org/wikipedia/en/thumb/0/0e/Comix_Zone_Coverart.png/220px-Comix_Zone_Coverart.png'
});
var game5 = ko.observable({
title: 'To the Moon',
genre: 'Visual Novel',
platform: 'PC',
releaseDate: '9/1/2011',
developer: 'Freebird Games',
publisher: 'Freebird Games',
imageURL: 'https://steamcdn-a.akamaihd.net/steam/apps/206440/capsule_616x353.jpg?t=1519836062'
});
function gamesViewModel() {
var self = this;
self.gamesList = ko.observableArray([game1, game2, game3, game4, game5]);
self.gameToAdd = ko.observable({
title: 'Mass Effect',
genre: 'RPG',
platform: 'PC',
releaseDate: '11/20/2007',
developer: 'BioWare',
publisher: 'EA',
imageURL: 'https://steamcdn-a.akamaihd.net/steam/apps/17460/header.jpg?t=1447351599'
});
self.addGame = function () {
self.gamesList.push(self.gameToAdd);
};
self.removeGame = function (gameToRemove) {
self.gamesList.remove(gameToRemove);
//var gameIndex = self.gamesList.indexOf(gameToRemove);
//self.gamesList.splice(gameIndex, 1);
};
}
ko.applyBindings(new gamesViewModel);
});
</script>
</head>
<div class="jumbotron">
<h1>TOP 5 GAMES</h1>
</div>
<div class="row">
<h4>Games</h4>
<div class="card-columns" data-bind="foreach: gamesList">
<div class="card">
<a data-bind="attr: {href: imageURL}" target="_blank">
<img class="card-img-top" data-bind="attr: {src: imageURL}" />
</a>
<div class="card-body">
<h5 class="card-title" data-bind="text: title"></h5>
<div class="card-text">
<div>
<span>Genre: </span>
<span data-bind="text: genre" />
</div>
<div>
<span>Platform: </span>
<span data-bind="text: platform" />
</div>
<div>
<span>Release Date: </span>
<span data-bind="text: releaseDate" />
</div>
<div>
<span>Developer: </span>
<span data-bind="text: developer" />
</div>
<div>
<span>Publisher: </span>
<span data-bind="text: publisher" />
</div>
</div>
<button class="btn btn-danger" data-bind="click: $parent.removeGame">-Remove</button>
</div>
</div>
</div>
<button data-bind="click: addGame">+Add</button>
</div>
Using "()" in knockoutjs is very tricky. Your code is perfect but here is the problem. game objects (game1, game2, ... ) are declared as observable (i would keep them as normal variable) and you are pushing observable reference in gamesList not actual values. Thats why remove method is not able to identify it.
Either declare game objects without observable or assign them with "()" in list.
$(function () {
var game1 = ko.observable({
title: 'Bioshock',
genre: 'Shooter',
platform: 'XBox 360',
releaseDate: '8/21/2007',
developer: 'Irrational Games',
publisher: '2K Games',
imageURL: 'https://upload.wikimedia.org/wikipedia/en/thumb/6/6d/BioShock_cover.jpg/220px-BioShock_cover.jpg'
});
var game2 = ko.observable({
title: 'The Legend of Zelda: Ocarina of Time',
genre: 'RPG',
platform: 'N64',
releaseDate: '11/21/1998',
developer: 'Nintendo',
publisher: 'Nintendo',
imageURL: 'https://cdn-images-1.medium.com/max/1600/1*n2iccNMASW983gg-ZmMdTw.jpeg'
});
var game3 = ko.observable({
title: 'Devil May Cry',
genre: 'Hack-n-Slash',
platform: 'PS2',
releaseDate: '8/23/2001',
developer: 'Capcom',
publisher: 'Capcom',
imageURL: 'https://upload.wikimedia.org/wikipedia/en/thumb/1/1e/DMC1FrontCover.jpg/220px-DMC1FrontCover.jpg'
});
var game4 = ko.observable({
title: 'Comix Zone',
genre: 'Beat-em-Up',
platform: 'Sega Genesis',
releaseDate: '8/2/1995',
developer: 'Sega',
publisher: 'Sega',
imageURL: 'https://upload.wikimedia.org/wikipedia/en/thumb/0/0e/Comix_Zone_Coverart.png/220px-Comix_Zone_Coverart.png'
});
var game5 = ko.observable({
title: 'To the Moon',
genre: 'Visual Novel',
platform: 'PC',
releaseDate: '9/1/2011',
developer: 'Freebird Games',
publisher: 'Freebird Games',
imageURL: 'https://steamcdn-a.akamaihd.net/steam/apps/206440/capsule_616x353.jpg?t=1519836062'
});
function gamesViewModel() {
var self = this;
self.gamesList = ko.observableArray([game1(), game2(), game3(), game4(), game5()]);
self.gameToAdd = ko.observable({
title: 'Mass Effect',
genre: 'RPG',
platform: 'PC',
releaseDate: '11/20/2007',
developer: 'BioWare',
publisher: 'EA',
imageURL: 'https://steamcdn-a.akamaihd.net/steam/apps/17460/header.jpg?t=1447351599'
});
self.addGame = function () {
self.gamesList.push(self.gameToAdd);
};
self.removeGame = function (gameToRemove) {
self.gamesList.remove(gameToRemove);
//var gameIndex = self.gamesList.indexOf(gameToRemove);
//self.gamesList.splice(gameIndex, 1);
};
}
ko.applyBindings(new gamesViewModel);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="jumbotron">
<h1>TOP 5 GAMES</h1>
</div>
<div class="row">
<h4>Games</h4>
<div class="card-columns" data-bind="foreach: gamesList">
<div class="card">
<a data-bind="attr: {href: imageURL}" target="_blank">
<img class="card-img-top" data-bind="attr: {src: imageURL}" />
</a>
<div class="card-body">
<h5 class="card-title" data-bind="text: title"></h5>
<div class="card-text">
<div>
<span>Genre: </span>
<span data-bind="text: genre" />
</div>
<div>
<span>Platform: </span>
<span data-bind="text: platform" />
</div>
<div>
<span>Release Date: </span>
<span data-bind="text: releaseDate" />
</div>
<div>
<span>Developer: </span>
<span data-bind="text: developer" />
</div>
<div>
<span>Publisher: </span>
<span data-bind="text: publisher" />
</div>
</div>
<button class="btn btn-danger" data-bind="click: $parent.removeGame">-Remove</button>
</div>
</div>
</div>
<button data-bind="click: addGame">+Add</button>
</div>
I'm still very basic with AngularJS (and programming in general honestly speaking. Having watched some videos online, I'm trying to understand the controller concept with the below example (e.g. passing an array and then iterating through it with ng-repeat). Have gone over this for the past hour and it works without the controller (e.g. with the array), but not when adding the array in a seperate script. Can anyone help me find my error in logic here - it literally is the same as the video, but I cannot see the error (or even a typo) and feel this is so fundamental, I should have this working, before moving on to the next steps.
Many thanks for any of your help:
<html ng-app>
<head><title>My First Page</title></head>
<body >
<div class="container" ng-controller="SimpleController">
Name:
<br />
<input type="text" ng-model="name" />
<br />
<ul>
<li ng-repeat="cust in customers"> {{ cust.name }} </li>
</ul>
</div>
<script src="script/angular.min.js"></script>
<script>
function SimpleController($scope) {
$scope.customers = [
{ name: 'Simon', lastname: 'Test' },
{ name: 'Thomas', lastname: 'Testi' },
{ name: 'Adi', lastname: 'Testo' },
{ name: 'Adrian', lastname: 'Testo' },
{ name: 'Tomeli', lastname: 'Testi' }
];
}
</script>
</body>
</html>
You are using global declaration of controller which is with angular 1.1 version. If you use version above 1.3 , you should declare the controller as follows,
var app = angular.module('testApp',[]);
app.controller('testCtrl',function($scope){
$scope.customers = [
{ name: 'Simon', lastname: 'Test' },
{ name: 'Thomas', lastname: 'Testi' },
{ name: 'Adi', lastname: 'Testo' },
{ name: 'Adrian', lastname: 'Testo' },
{ name: 'Tomeli', lastname: 'Testi' }
];
});
DEMO
var app = angular.module('testApp',[]);
app.controller('SimpleController',function($scope){
$scope.customers = [
{ name: 'Simon', lastname: 'Test' },
{ name: 'Thomas', lastname: 'Testi' },
{ name: 'Adi', lastname: 'Testo' },
{ name: 'Adrian', lastname: 'Testo' },
{ name: 'Tomeli', lastname: 'Testi' }
];
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="testApp">
<div class="container" ng-controller="SimpleController">
Name:
<br />
<input type="text" ng-model="name" />
<br />
<ul>
<li ng-repeat="cust in customers"> {{ cust.name }} </li>
</ul>
</div>
</body>
What is the mistake in my code? cust.name and cust.city are not displaying.
Why are no list items created?
<html>
<body>
<div data-ng-controller="SimpleController">
Name :
<br />
<input type="text" data-ng-model="name" placeholder="Enter Your Name " /> {{ name }}
<br />
<ul>
<li data-ng-repeat="cust in customers | filter:name | orderBy:'city' ">
{{ cust.name | uppercase }} - {{ cust.city | lowercase }}
</li>
</ul>
</div>
<script src="angular.min.js"></script>
<script>
function SimpleController($scope) {
$scope.customers = [
{
name: 'Rishabh Shrivas',
city: 'New Delhi'
},
{
name: 'Rishabh Bharadawaj',
city: 'Noida'
},
{
name: 'Rishabh Sen',
city: 'Gurgaon'
}
];
}
</script>
</body>
</html>
You need an ng-app section in the HTML, even an empty one is sufficient. Also, you need to create the controller differently:
var myApp = angular.module('myApp',[]);
myApp.controller('SimpleController', ['$scope', function($scope) {
$scope.customers = [
{
name: 'Rishabh Shrivas',
city: 'New Delhi'
},
{
name: 'Rishabh Bharadawaj',
city: 'Noida'
},
{
name: 'Rishabh Sen',
city: 'Gurgaon'
}
];
}]);
This is not displaying data, I am learning about controllers. Why it is not displaying data while it displays data in the video I am watching.
<div data-ng-controller="FirstController">
<input type="text" name="txtName" data-ng-model="typedName" />
<br />
Typed Name is: {{ typedName }}
<br />
Names:
<ul >
<li data-ng-repeat="person in Customers | orderBy:'name' | filter:typedName "> {{ person.name | uppercase}} - {{ person.city }}
</li>
</ul>
</div>
<script>
function FirstController($scope) {
$scope.Customers = [
{ name: 'Sita', city: 'Los Angeles' },
{ name: 'Ram', city: 'Los Vegas' },
{ name: 'Amit', city: 'San Antonio' },
{ name: 'Cat', city: 'Arkanas' },
{ name: 'Boushick', city: 'Pittsburgh' }
];
}
</script>
<script src="Scripts/angular.min.js"></script>
Looks like you're following older videos where they mmight be using angular 1.2.
In latest version of angular, it's mandatory to specific app name and declare controllers under those modules. Though you can activate global controller functions via config but its not recommended.
So you need to make the following changes:
In your HTML,
<html data-ng-app="myApp">
NOw in your JS for controller:
angular.module("myApp", [])
.controller("ControllerName", function($scope) {
// declare your $scope data here
})
Why global controller functions are deprecated?
When you declare controller functions globally, It will be polluting the global namespace. Assume there is another library which is using the same function name, then your function would be overriden.
For example,
you have function SimpleController in your file. Assume some third party library you're using, they also use same name for some functionality.
They set,
window.SimpleController = window.alert
So it means your controller function has been overriden.
that's why it's been deprecated.
From the code you provided I believe its not working because you have not declared an Angular Module in your javascript and linked it to your html view via ng-app. Please check the working Plunker below.
http://plnkr.co/edit/fwwzZwODfZ9G5Ml1Y1MS?p=preview
<body ng-app="myApp">
<div ng-controller="FirstController">
<input type="text" name="txtName" ng-model="typedName" />
<br />
Typed Name is: {{ typedName }}
<br />
Names:
<ul>
<li data-ng-repeat="person in Customers | orderBy:'name' | filter:typedName ">
{{ person.name | uppercase}} - {{ person.city }}
</li>
</ul>
</div>
<script>
angular.module('myApp', [])
.controller('FirstController', function($scope) {
$scope.Customers = [
{ name: 'Sita', city: 'Los Angeles' },
{ name: 'Ram', city: 'Los Vegas' },
{ name: 'Amit', city: 'San Antonio' },
{ name: 'Cat', city: 'Arkanas' },
{ name: 'Boushick', city: 'Pittsburgh' }
];
});
</script>
</body>
I tried the following code:
var app = angular.module('app', ['ngRoute', 'dx'])
app.controller('IndexCtrl', function($scope){
var contacts = [
{ name: "Barbara J. Coggins", phone: "512-964-2757", email: "BarbaraJCoggins#rhyta.com", category: "Family" },
{ name: "Carol M. Das", phone: "360-684-1334", email: "CarolMDas#jourrapide.com", category: "Friends" },
{ name: "Janet R. Skinner", phone: "520-573-7903", email: "JanetRSkinner#jourrapide.com", category: "Work" }
];
$scope.slideOutOptions = {
dataSource: contacts,
itemTemplate: 'item',
menuItemTemlate: 'menuItem'
}
})
<!-- HTML -->
<div class="app-index" ng-controller="IndexCtrl">
<div dx-slideout="slideOutOptions">
<div data-options="dxTemplate: { name: 'item' }">
<h1 data-bind="text: category"></h1>
<p><b>Name:</b> <span data-bind="text: name"></span></p>
<p><b>Phone:</b> <span data-bind="text: phone"></span></p>
<p><b>e-mail:</b> <span data-bind="text: email"></span></p>
</div>
<div data-options="dxTemplate: { name: 'menuItem' }">
<b data-bind="text: name"></b>
</div>
</div>
</div>
AngularJS there is not enough documentation on the DevExpress site. there are only examples using Knockout. Checkout PhoneJS DXSlideOut Documentation
The problem is in the HTML templates. You should use Angular syntax there.
<div dx-slideout="slideOutOptions">
<div data-options="dxTemplate: { name: 'item' }">
<h1>{{category}}</h1>
<p><b>Name:</b> <span>{{name}}</span></p>
<p><b>Phone:</b> <span>{{phone}}</span></p>
<p><b>e-mail:</b> <span>{{email}}</span></p>
</div>
<div data-options="dxTemplate: { name: 'menuItem' }">
<b>{{name}}</b>
</div>
</div>
Checkout docs about Angular approach.