my first post on stackoverflow. (and english is not my native tongue).
I am trying to learn how to use emberjs.
It's not easy because of the lack of good tutorials.
So I decided to code a chat, I use nodejs and socket.io server-side.
Html
<script type="text/x-handlebars">
<div class="page">
<div class="users">
</div>
<div class="messagebox">
{{#view App.TextField valueBinding="currentMsg" placeholder="your message"}}{{/view}}
<button {{action "sendMsg"}}>Send</button>
</div>
<div id="chatbox">
{{#collection contentBinding="App.MsgsController" tagName="ul"}}
<b>{{value}}</b>
{{/collection}}
</div>
</div>
</script>
Javascript
var id;
var socketio = io.connect("127.0.0.1:8888");
socketio.on('id', function (data) {
id = data;
});
socketio.on("broadcast", function (data) {
if (id == data.id) {
return
}
App.MsgsController.addMsg(data.message);
});
socketio.on("own", function (data) {
App.MsgsController.addMsg(data.message);
});
App = Ember.Application.create();
App.Msg = Ember.Object.extend({
value: null
});
App.MsgsController = Ember.ArrayController.create({
content: [],
addMsg: function (value) {
var msg = App.Msg.create({
value: value
});
this.pushObject(msg);
}
});
App.TextField = Ember.TextField.extend({
insertNewline: function() {
this.get("controller").send("sendMsg");
}
});
App.ApplicationController = Ember.Controller.extend({
currentMsg: 't',
sendMsg: function () {
var currentMsg = this.get('currentMsg');
if(currentMsg) {
socketio.emit("message", { message: currentMsg, id: id});
this.set('currentMsg', '');
}
}
});
I want to focus App.TextField after the App.ApplicationController.sendMsg call.
I tried
App.TextField.$().focus()
but it seems that I can only use $() inside of its methods.
Someone can help me, please?
Edit :
Ok, I found the answer.
App.TextField is like "class", and the one on the view is an instance.
I must add an id in my view
{{#view App.TextField valueBinding="currentMsg" placeholder="your message" id="mytextfield"}}{{/view}}
and use jquery selector to access to the instance
$('#mytextfield').focus();
Use didInsertElement hook for the view to handle jquery methods.
http://emberjs.com/api/classes/Ember.View.html#event_didInsertElement
Related
I need to call an AngularJS function call from javascript-side.
The below is the function I want to call from javascript.
https://github.com/aws-samples/aws-iot-examples/blob/master/mqttSample/js/app.js
AppController.$inject = ['$scope'];
AppController.prototype.createClient = function() {
var options = {
clientId : this.clientId,
endpoint: this.endpoint.toLowerCase(),
accessKey: this.accessKey,
secretKey: this.secretKey,
regionName: this.regionName
};
var client = this.clients.getClient(options);
if (!client.connected) {
client.connect(options);
}
};
My javascript
<body>
<div id='myid' class="container" ng-app="awsiot.sample" ng-controller="AppController as vm">
....
<div class="form-group">
<button class="btn btn-primary" id='myclick' ng-click="vm.createClient()" >Create Client</button> <-- working! -->
</div>
....
<script>
angular.element('#myid').scope().createClient(); // not working!
</script>
Can you help me?
try this:
angular.element(document.querySelector('#myid')).controller().info();
demo https://stackblitz.com/edit/angularjs-wxjhgd
you can tweak it to suit your needs
To call createClient() in angular is what I want to accomplish
Put the call in the $onInit function of the controller:
function AppController() {
this.$onInit = function() {
this.createClient();
});
}
For more information, see AngularJS $compile Service API Reference - Life-Cycle Hooks.
The fruit is just so I can make sure it works. Then I will make it work with mlab
Here is what I have in my html page I want it to show in.
<body ng-controller="PackingController as vm">
<h2>List of fruits</h2>
<li ng-repeat="fruit in vm.fruits">{{fruit}}</li>
</body>
In my packingcomponents.js page I have it like this.
class PackingController {
constructor($http) {
this.pack = "are you here";
this.packing = $http({
method: "GET",
url: "/api/camp"
//handels success
}).then(function mySuccess(response) {
console.log(response.data);
return response.data;
//handels errors
}, function myError(response) {
return response.statusText;
});
this.packinglist = this.packing;
console.log(this.packing);
}
}
Then last page I have is my angular_app.js page.
app.controller("PackingController", PackingController)
this.hello = "world";
this.fruits = ["apples", "oranges", "berries"];
Right now I am trying to just get it to work then make it show my packing list on the page.
If you are using AngularJs Modify these part of codes:
1-Use this template for Your controllers
(function() {
"use strict";
angular.module("app")
.controller("PackingController", PackingController);
/* #ngInject */
function PackingController(factory) {
var vm = this;
//-------------------------------variables
vm.fruits = [];
//-------------------------------functions
main();
function main() {
// call factory and get controller's data
}
}
})();
2-Modify your html codes
<div ng-controller="PackingController as vm">
<h2>List of fruits</h2>
<ul>
<li ng-repeat="fruit in vm.fruits">{{fruit}}</li>
</ul>
</div>
I am new to knockout.js and am trying to create a simple notification message component. What's happening is that the binding appears to occur, but there are no updates happening to the UI. Below is the code, and I would appreciate any help in locating where this is falling down.
Please note: I am using ASP.NET MVC 5, Knockout.js 3.2.0, Require.js 2.1.14 with AMD for accessing scripts and views.
View - Hub
<div class="row">
<notification-hub></notification-hub>
</div>
<button type="button">Push Me!</button>
#section scripts {
<script src="~/Scripts/Views/Home/index.js" type="text/javascript"></script>
}
Hub Script
require(["ko", "jquery", "ViewModels/notificationMessage", "Components/Notifications/hub", "Plugins/jquery.timeago"], function (ko, jquery, notificationMessage, notificationHub) {
try {
// Register the component.
ko.components.register("notification-hub", {
viewModel: notificationHub,
template: { require: "text!/Components/Notifications/HubItemView" }
});
// Create an instance of the hub and add an inital message.
var hub = new notificationHub();
hub.addMessage(new notificationMessage("Test", "This is a test message.", "2015-02-06 11:00 AM"));
// Bind things up.
ko.applyBindings(hub, $("notification-hub")[0]);
// Create a handler for the button click.
$("button").on("click", function () {
hub.addMessage(new notificationMessage("New Message", "This is a new message", new Date().toLocaleDateString()));
});
}
catch (e) {
$("#displayValues").html("Something went wrong...");
Debug.writeln("Script error: " + e.message);
}
});
ViewModel - Hub
define(["ko", "jquery"], function (ko, jquery) {
// Create the hub's main ViewModel.
function notificationHub() {
var self = this;
// Define the Properties.
self.messages = ko.observableArray();
self.count = ko.computed(function () { return self.messages().length; });
}
// Define the addMessage method.
notificationHub.prototype.addMessage = function (msg) {
var self = this;
// Pop message to the top of the stack.
self.messages().push(msg);
Debug.writeln("Count of message array: " + self.messages().length);
}
return notificationHub;
});
View - Message Model
<p data-bind="if: messages().length == 0">Unfortunately we didn't find any records.</p>
<ul data-bind="foreach: messages">
<li class="notificationMessage">
<span class="timeAgo" data-bind="text: createdDate"></span>
<h2 data-bind="text: title"></h2>
<p data-bind="text: message"></p>
</li>
</ul>
<!-- For debugging purposes -->
<input type="text" data-bind="value: count" />
ViewModel - Message Model
define(["ko"], function (ko) {
// Define the ViewModel for the messages themselves.
return function notificationMessage(title, message, date) {
var self = this;
// Define the Properties.
self.title = title;
self.message = message;
self.createdDate = date;
};
});
I use Web Api and Knockout.js in my project. I want to try like this: if I click the "Home" I want to refresh just main div. So I write this code.
My script in layout.cshtml
<script type="text/javascript">
$(document).ready(function () {
ko.applyBindings(new TalesViewModel());//First load the code is runnig and load the main div
function TalesViewModel() {
var self = this;
self.tales = ko.observableArray();
$.getJSON("/api/tales/", self.tales);
}
$('#home').click(function () {
var Tale = function (TaleName, Content, VoicePath, Tales) {
self = this;
self.TaleName = TaleName;
self.Content = Content;
self.VoicePath = VoicePath;
}
var mapping = {
'tales': {
create: function (options) {
return new Tale(options.data.TaleName, options.data.Content,
options.data.VoicePath);
}
}
}
var data = $.getJSON("/api/tales/", Tale);
var viewModel = ko.mapping.fromjs(data, mapping);
ko.applyBindings(viewModel);
})
})
</script>
I want to refresh this place
<div id="main">
#RenderBody()
</div>
TaleList.cshtml (PartialView)
<div>
<ul data-bind="foreach: tales">
<li>
<div>
<div>Masal Adı</div>
<span data-bind="text: $data.TaleName"></span>
</div>
<div>
<div>İçerik</div>
<span data-bind="text: $data.Content"></span>
</div>
<div>
<div>Ses Dosyası</div>
<span data-bind="text: $data.VoicePath"></span>
</div>
</li>
</ul>
When I clicked Home main div is refresh but no data in here. I think I have to use Knockout something but I don't know how can I do it.
I hope I can explain. Thanks all replies.
Update
If I check with firebug I see this error "TypeError: Object # has no method 'fromjs'"
Update2
I added my first knockout code when I load the project.
This is what you need to do:
Create a js object
var Tale = function (TaleName, Content, VoicePath, Tales) {
self = this;
self.TaleName = TaleName;
self.Content = Content;
self.VoicePath = VoicePath;
}
Create a mapping to convert to your js objects
var mapping = {
'tales': {
create: function(options) {
return new Tale(options.data.TaleName, options.data.Content,
options.data.VoicePath);
}
}
}
Check that your data matches something like below, checking the names match as below:
var data = {"tales" : [{"TaleName": "T1", "Content":"c1", "VoicePath":"v1"}, {"TaleName": "T2", "Content":"c2", "VoicePath":"v2"}]}
var viewModel = ko.mapping.fromJS(data, mapping);
Apply the bindings
ko.applyBindings(viewModel);
Here is a working fiddle with mimicked data
http://jsfiddle.net/dxJpc/1/
Update
You are mixing a combination of getJson and ajax, you only need one.
This can be replaced: (With Ajax)
$.ajax({
type: 'GET',
url: '/Pages/TaleList/',
contentType: 'application/html; charset=utf-8',
dataType: 'html'
})
.success(function (data) {
alert("okey!")
var viewModel = ko.mapping.fromJS(data, mapping);
ko.applyBindings(viewModel);
})
.error(function (req, status, error) {
alert("Error!Occured")
})
With getJSON:
var data = $.getJSON("/api/tales/", Tale);
var viewModel = ko.mapping.fromJS(data, mapping);
ko.applyBindings(viewModel);
Update 3
If you are loading your initial load as you have changed it to, you can simply put this in your on click event:
$('#home').click(function () {
ko.applyBindings(new TalesViewModel());
})
Update 4
Declare the view model in the document ready.
$(document).ready(function () {
var viewModel = new TalesViewModel();
ko.applyBindings(viewModel);
Then change your click to this:
$(document).ready(function () {
viewModel = new TalesViewModel();
I might be missing something really simple but can anyone point out where i'm doing wrong here?
many thanks in advance.
<div data-bind="foreach: agencies">
<div data-bind="text:name"></div>
<div data-bind="text:email"></div>
<button data-bind="click: removeAgency">remove</button>
</div>
<script type="text/javascript">
var agency = [{
name : ko.observable('a'),
email : ko.observable('b')
}, {
name: ko.observable('c'),
email: ko.observable('d')
}];
var vm = {
agencies: ko.observableArray(agency),
removeAgency: function(agency) {
this.agencies.remove(agency);
}
};
ko.applyBindings(vm);
</script>
this is the error i get: Uncaught Error: Unable to parse bindings.
Message: ReferenceError: removeAgency is not defined;
Bindings value: click: removeAgency
You are binding to an agency in that html, but your method is on your viewmodel. Try something like:
<button data-bind="click: $parent.removeAgency">remove</button>
You might need to re-jig your vm to get the scope correct:
var ViewModel = function(){
var self = this;
self.agencies = ko.observableArray(agency),
self.removeAgency = function(agency) {
self.agencies.remove(agency);
}
};
var vm = new ViewModel();
I still get confused at times with scope, I have to admit, but give this a try and see what happens.
Working example:
http://jsfiddle.net/marko4286/7RDc3/2034/
Read documentation http://knockoutjs.com/documentation/foreach-binding.html