英文:
How to Call A Function inside a Ko.Observable Array? Knockout
问题
I'm learning more about knockout.js. I have built a little dialogue system using it and it works! One thing I'd like to do is have a function that can jump from the data after a button is pressed to run a new function.
How the data below works is there's text that shows, the image changes, and the choices are buttons that when pressed go to the next story/data set. In this case, it goes back to the start (storyLink 1).
Here's a snippet of my data with said function:
"106":{"text":"[The game ended you Died.]",
"image": "death face.gif",
"choices":[{"choiceText":"Oops.","storyLink":"1", function () { console.log("lmao");}}]},
Here is a snippet of the HTML:
<div data-bind="with: activeStory">
<img data-bind="attr: { src: image }">
<button id="button" class="Button-data imgLink" onclick="handleClick()" data-bind="click: $root.onChoice, text: choiceText"></button>
Here's a bit of the view model. I did not include the part where the bindings are applied, as that's a chunk of code that takes the text above and creates a typewriter effect:
var activeStoryId = ko.observable(1)
.extend({ notify: "always" });
var activeStory = ko.pureComputed(() =>
story[activeStoryId()] ??
{ text: "[There was an Error.]", choices: [{ choiceText: "Back to start", storyLink: 1 }] }
);
var onChoice = ({ storyLink }) => activeStoryId(storyLink);
// Apply bindings
registerBinding();
ko.applyBindings({
onChoice,
activeStory
});
This isn't running, and I assume this is because of a syntax error or perhaps I need to call it a different way. I keep finding my syntax is wrong when using knockout, so any insight would be great!
Edit 2:
Here's an example of what I am trying to figure out:
let a = 1;
let b = 2;
let arr = [
a,
b,
function () {
return a + b;
},
];
console.log(arr[2]()); // returns 3
console.log(typeof arr); // returns object
In this code, there's a function that runs inside the array. It doesn't currently work in my code when I try to do this.
英文:
I'm learning more about knockout.js. I have built a little dialogue system using it and it works! One thing I'd like to do, is have a function that can jump from the data after a button is pressed to run a new function.
How the data below works is there's text that shows, the image changes, and the choices are buttons that when pressed go to the next story/data set. In this case it goes back to the start (storyLink 1).
Here's a snippet of my data with said function:
"106":{"text":"[The game ended you Died.]",
"image": "death face.gif",
"choices":[{"choiceText":"Oops.","storyLink":"1", function () { console.log("lmao");}}]},
here is a snippet of the html:
<div data-bind="with: activeStory">
<img data-bind="attr: { src: image }">
<button id ="button" class ="Button-data imgLink" onclick = "handleClick()" data-bind="click: $root.onChoice, text: choiceText"></button>
here's a bit of the view model. I did not include the part where the bindings are applied as that's a chunk of code that takes the text above and creates a typewriter effect.
var activeStoryId = ko.observable(1)
.extend({ notify: "always" });
var activeStory = ko.pureComputed(() =>
story[activeStoryId()] ??
{ text: "[There was an Error.]", choices: [{ choiceText: "Back to start", storyLink: 1 }] }
);
var onChoice = ({ storyLink }) => activeStoryId(storyLink);
// Apply bindings
registerBinding();
ko.applyBindings({
onChoice,
activeStory
});
This isn't running, and I assume this is because of a syntax error or perhaps I need to call it a different way. I keep finding my syntax is wrong when using knockout so any insight would be great!
I tried adjusting the syntax based on Javascript arrays and I'm still missing something. I haven't found a solution that works yet.
Edit 2:
Here's an example of what I am trying to figure out:
let a = 1;
let b = 2;
let arr = [
a,
b,
function () {
return a + b;
},
];
console.log(arr[2]()); // return 3
console.log(typeof arr); // returns object
In this code, there's a function that runs inside the array. It doesn't currently work in my code when I try to do this.
答案1
得分: 1
Here is the translated content:
我认为我理解了你想要做什么。希望这会有所帮助。
var story = {
"1": {
"text": "[游戏结束,你死了。]",
"image": "death_face.gif",
"choices": [{
"choiceText": "糟糕。",
"storyLink": "1"
}, {
"choiceText": "差一点……",
"storyLink": "2"
}]
},
"2": {
"text": "[开始新故事]",
"image": "happy_face.gif",
"choices": [{
"choiceText": "我们走吧。",
"storyLink": "1"
}, {
"choiceText": "也许下次吧。",
"storyLink": "2"
}]
}
};
function ViewModel() {
var self = this;
self.activeStoryId = ko.observable(1)
.extend({
notify: "always"
});
self.activeStory = ko.pureComputed(() =>
story[self.activeStoryId()] ?? {
text: "[发生了错误。]",
choices: [{
choiceText: "回到起点",
storyLink: 1
}]
}
);
self.onChoice = function(item) {
console.log(item);
self.activeStoryId(item.storyLink);
}
}
var vm = new ViewModel();
ko.applyBindings(vm);
如果我理解正确,如果你想要将函数作为数据的一部分传递,你可以像下面这样做。拥有一个在你的选择对象之间相同的函数名称,然后你可以将该函数对象传递给click绑定以运行它。
var story = {
"1": {
"text": "[游戏结束,你死了。]",
"image": "death_face.gif",
"choices": [{
"choiceText": "糟糕。",
"storyLink": "1",
"choiceCommand": function () { console.log("storylink 1-1") }
}, {
"choiceText": "差一点……",
"storyLink": "2",
"choiceCommand": function () { console.log("storylink 1-2") }
}]
},
"2": {
"text": "[开始新故事]",
"image": "happy_face.gif",
"choices": [{
"choiceText": "我们走吧。",
"storyLink": "1",
"choiceCommand": function () { console.log("storylink 2-1") }
}, {
"choiceText": "也许下次吧。",
"storyLink": "2",
"choiceCommand": function () { console.log("storylink 2-2") }
}]
}
};
希望这对你有所帮助!
英文:
I think I understand what you are tying to do. Hopefully this will help.
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
var story = {
"1": {
"text": "[The game ended you Died.]",
"image": "death_face.gif",
"choices": [{
"choiceText": "Oops.",
"storyLink": "1"
}, {
"choiceText": "So close...",
"storyLink": "2"
}]
},
"2": {
"text": "[Start New Story]",
"image": "happy_face.gif",
"choices": [{
"choiceText": "Away we go.",
"storyLink": "1"
}, {
"choiceText": "Maybe next time",
"storyLink": "2"
}]
}
};
function ViewModel() {
var self = this;
self.activeStoryId = ko.observable(1)
.extend({
notify: "always"
});
self.activeStory = ko.pureComputed(() =>
story[self.activeStoryId()] ?? {
text: "[There was an Error.]",
choices: [{
choiceText: "Back to start",
storyLink: 1
}]
}
);
self.onChoice = function(item) {
console.log(item);
self.activeStoryId(item.storyLink);
}
}
var vm = new ViewModel();
ko.applyBindings(vm);
<!-- language: lang-html -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<div data-bind="with: activeStory">
<h2 data-bind="text: text"></h2>
<img data-bind="attr: { src: image }">
<!-- ko foreach: choices -->
<button id="button" class="Button-data imgLink" data-bind="click: $root.onChoice, text: choiceText"></button>
<!-- /ko -->
</div>
<!-- end snippet -->
EDIT
If I understand correctly, if you want to be passing functions as part of your data, I would do something like the following. Have a function name that is the same across your choice objects. then you can pass that function object to the click binding for it to run.
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
var story = {
"1": {
"text": "[The game ended you Died.]",
"image": "death_face.gif",
"choices": [{
"choiceText": "Oops.",
"storyLink": "1",
"choiceCommand": function () { console.log("storylink 1-1")}
}, {
"choiceText": "So close...",
"storyLink": "2",
"choiceCommand": function () { console.log("storylink 1-2")}
}]
},
"2": {
"text": "[Start New Story]",
"image": "happy_face.gif",
"choices": [{
"choiceText": "Away we go.",
"storyLink": "1",
"choiceCommand": function () { console.log("storylink 2-1")}
}, {
"choiceText": "Maybe next time",
"storyLink": "2",
"choiceCommand": function () { console.log("storylink 2-2")}
}]
}
};
function ViewModel() {
var self = this;
self.activeStoryId = ko.observable(1)
.extend({
notify: "always"
});
self.activeStory = ko.pureComputed(() =>
story[self.activeStoryId()] ?? {
text: "[There was an Error.]",
choices: [{
choiceText: "Back to start",
storyLink: 1
}]
}
);
self.onChoice = function(item) {
console.log(item);
self.activeStoryId(item.storyLink);
}
}
var vm = new ViewModel();
ko.applyBindings(vm);
<!-- language: lang-html -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<div data-bind="with: activeStory">
<h2 data-bind="text: text"></h2>
<img data-bind="attr: { src: image }">
<!-- ko foreach: choices -->
<button id="button" class="Button-data imgLink" data-bind="click: choiceCommand, text: choiceText"></button>
<!-- /ko -->
</div>
<!-- end snippet -->
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论