Knockout.js 和选择列表不更新 Jquery 模板中的属性

发布于 2024-12-02 07:00:04 字数 5462 浏览 0 评论 0原文

我不确定为什么我的依赖可观察 URL 没有在选择列表更改时更新。 iframe 应更新选择更改事件上的 url,但没有任何反应。虽然依赖的可观察量是这样的,但是模板没有被更新。它在没有模板的情况下仅使用静态定义的 HTML 工作,但不是我尝试创建模板并且 iframe 不更新。

查看

    @model AvatarViewModel
    @{
        ViewBag.Title = "Index";
        Layout = "~/Areas/Admin/Views/Shared/_AdminLayout.cshtml";
    }
    <div data-bind='template: { name: "editableAgentTemplate", data: caseStudy.instructor }'>
    </div>
    <div data-bind='template: { name: "editableAgentTemplate", data: caseStudy.assistantInstructor }'>
    </div>
    <div data-bind='template: { name: "editableAgentTemplate", data: caseStudy.opponent }'>
    </div>
    <script id="editableAgentTemplate" type="text/html">
        <div>
        <div>
            <iframe style="width: 125px; height: 100px; border: none" scrolling="no" frameborder="0"
                 data-bind="attr: { id: name, name: name, src: url }">
            </iframe>
        </div>
        <select data-bind="options: agents, optionsText: 'Title', optionsValue: 'Id', value: selectedId,">
        </select>
        <button data-bind="click: function() { caseStudy.saveAvatar(name, id) }">
            Update
        </button>
        <input type="text" data-bind="value: text" />
        <button data-bind="click: function() { app.viewModel.caseStudy.speak(text, name) }">
            Speak
        </button>
    </div>
    </script>
    @section Script {
        <script src="/Scripts/app.avatars.js" type="text/javascript"></script>
        <script src="/Areas/Admin/Scripts/app.admin.casestudy.avatars.js" type="text/javascript"></script>
        <script type="text/javascript">
            app.avatars.init(@Html.Raw(@Model.Avatars.ToJson()));
            app.admin.caseStudy.init('@ApplicationAvatarType.Instructor.ToString()', '@ApplicationAvatarType.AssistantInstructor', '@ApplicationAvatarType.Opponent');
        </script>
    }

JS文件

(function (app, $, undefined) {

    app.viewModel = app.viewModel || {};
    app.admin.caseStudy = app.admin.caseStudy || {};

    var controller = '/Admin/CaseStudy/Avatars';

    var urls = {
        GET_AVATARS: controller + '/GetAvatars',
        SAVE_AVATAR: controller + '/SaveAvatar'
    };

    var editableAgent = function () {
        this.id = ko.observable(0);
        this.selectedId = ko.observable(0),
        this.name = ko.observable('');
        this.text = ko.observable('');
        this.agents = ko.observableArray();
        this.url = ko.dependentObservable(function () {
            console.log('url');
            if (this.selectedId())
            return '/Avatar/Avatar?assetId=' + this.selectedId();
        else {
            return '';
        }
        }, this);
    };

    app.viewModel.caseStudy = {
        instructor: ko.observable(new editableAgent()),
        assistantInstructor: ko.observable(new editableAgent()),
        opponent: ko.observable(new editableAgent()),
        agents: ko.observableArray()
    };

    app.viewModel.caseStudy.speak = function (text, type) {
        if (text().length > 0) {
            app.avatars.addAction({ AgentName: type(), Text: text(), Speech: text() });
            app.avatars.speak();
        }
    };

    app.admin.caseStudy.init = function (instructor, assistantInstructor, opponent) {

        app.viewModel.caseStudy.instructor().name(instructor);
        app.viewModel.caseStudy.assistantInstructor().name(assistantInstructor);
        app.viewModel.caseStudy.opponent().name(opponent);

        app.admin.caseStudy.getAvatars(function () {
            app.applyBindings();
        });
    };


    app.admin.caseStudy.getAvatars = function (callback) {
        var options = {
            url: urls.GET_AVATARS,
            callback: function (json) {
                if (json) {

                    app.viewModel.caseStudy.agents(json.Avatars);
                    app.viewModel.caseStudy.instructor().agents(json.Avatars);
                    app.viewModel.caseStudy.opponent().agents(json.Avatars);
                    app.viewModel.caseStudy.assistantInstructor().agents(json.Avatars);
                    app.viewModel.caseStudy.instructor().selectedId(json.Instructor.AssetId);
                    app.viewModel.caseStudy.opponent().selectedId(json.Opponent.AssetId);
                    app.viewModel.caseStudy.assistantInstructor().selectedId(json.AssistantInstructor.AssetId);
                    app.viewModel.caseStudy.instructor().id(json.Instructor.AssetId);
                    app.viewModel.caseStudy.opponent().id(json.Opponent.AssetId);
                    app.viewModel.caseStudy.assistantInstructor().id(json.AssistantInstructor.AssetId);

                    if (typeof (callback) === 'function') {
                        callback();
                    }
                }
            }
        };

        app.makeRequest(options);
    };

    app.viewModel.caseStudy.saveAvatar = function (type, assetId) {
        var options = {
            url: urls.SAVE_AVATAR + '?type=' + type + '&assetId=' + assetId,
            callback: function (json) {
                if (json) {
                    alert('Saved');

                }
            }
        };

        app.makeRequest(options);
    };

})(window.app = window.app || {}, jQuery);

I am not sure why my dependent observable URL is not being updated on a select list change. The iframe should update the url on the select on change event but nothing happens. The dependent observable is being this though, but the template isn't being updated. It worked without the template with just statically defined HTML, but not I tried to create a template and the iframe doesn't update.

View

    @model AvatarViewModel
    @{
        ViewBag.Title = "Index";
        Layout = "~/Areas/Admin/Views/Shared/_AdminLayout.cshtml";
    }
    <div data-bind='template: { name: "editableAgentTemplate", data: caseStudy.instructor }'>
    </div>
    <div data-bind='template: { name: "editableAgentTemplate", data: caseStudy.assistantInstructor }'>
    </div>
    <div data-bind='template: { name: "editableAgentTemplate", data: caseStudy.opponent }'>
    </div>
    <script id="editableAgentTemplate" type="text/html">
        <div>
        <div>
            <iframe style="width: 125px; height: 100px; border: none" scrolling="no" frameborder="0"
                 data-bind="attr: { id: name, name: name, src: url }">
            </iframe>
        </div>
        <select data-bind="options: agents, optionsText: 'Title', optionsValue: 'Id', value: selectedId,">
        </select>
        <button data-bind="click: function() { caseStudy.saveAvatar(name, id) }">
            Update
        </button>
        <input type="text" data-bind="value: text" />
        <button data-bind="click: function() { app.viewModel.caseStudy.speak(text, name) }">
            Speak
        </button>
    </div>
    </script>
    @section Script {
        <script src="/Scripts/app.avatars.js" type="text/javascript"></script>
        <script src="/Areas/Admin/Scripts/app.admin.casestudy.avatars.js" type="text/javascript"></script>
        <script type="text/javascript">
            app.avatars.init(@Html.Raw(@Model.Avatars.ToJson()));
            app.admin.caseStudy.init('@ApplicationAvatarType.Instructor.ToString()', '@ApplicationAvatarType.AssistantInstructor', '@ApplicationAvatarType.Opponent');
        </script>
    }

JS File

(function (app, $, undefined) {

    app.viewModel = app.viewModel || {};
    app.admin.caseStudy = app.admin.caseStudy || {};

    var controller = '/Admin/CaseStudy/Avatars';

    var urls = {
        GET_AVATARS: controller + '/GetAvatars',
        SAVE_AVATAR: controller + '/SaveAvatar'
    };

    var editableAgent = function () {
        this.id = ko.observable(0);
        this.selectedId = ko.observable(0),
        this.name = ko.observable('');
        this.text = ko.observable('');
        this.agents = ko.observableArray();
        this.url = ko.dependentObservable(function () {
            console.log('url');
            if (this.selectedId())
            return '/Avatar/Avatar?assetId=' + this.selectedId();
        else {
            return '';
        }
        }, this);
    };

    app.viewModel.caseStudy = {
        instructor: ko.observable(new editableAgent()),
        assistantInstructor: ko.observable(new editableAgent()),
        opponent: ko.observable(new editableAgent()),
        agents: ko.observableArray()
    };

    app.viewModel.caseStudy.speak = function (text, type) {
        if (text().length > 0) {
            app.avatars.addAction({ AgentName: type(), Text: text(), Speech: text() });
            app.avatars.speak();
        }
    };

    app.admin.caseStudy.init = function (instructor, assistantInstructor, opponent) {

        app.viewModel.caseStudy.instructor().name(instructor);
        app.viewModel.caseStudy.assistantInstructor().name(assistantInstructor);
        app.viewModel.caseStudy.opponent().name(opponent);

        app.admin.caseStudy.getAvatars(function () {
            app.applyBindings();
        });
    };


    app.admin.caseStudy.getAvatars = function (callback) {
        var options = {
            url: urls.GET_AVATARS,
            callback: function (json) {
                if (json) {

                    app.viewModel.caseStudy.agents(json.Avatars);
                    app.viewModel.caseStudy.instructor().agents(json.Avatars);
                    app.viewModel.caseStudy.opponent().agents(json.Avatars);
                    app.viewModel.caseStudy.assistantInstructor().agents(json.Avatars);
                    app.viewModel.caseStudy.instructor().selectedId(json.Instructor.AssetId);
                    app.viewModel.caseStudy.opponent().selectedId(json.Opponent.AssetId);
                    app.viewModel.caseStudy.assistantInstructor().selectedId(json.AssistantInstructor.AssetId);
                    app.viewModel.caseStudy.instructor().id(json.Instructor.AssetId);
                    app.viewModel.caseStudy.opponent().id(json.Opponent.AssetId);
                    app.viewModel.caseStudy.assistantInstructor().id(json.AssistantInstructor.AssetId);

                    if (typeof (callback) === 'function') {
                        callback();
                    }
                }
            }
        };

        app.makeRequest(options);
    };

    app.viewModel.caseStudy.saveAvatar = function (type, assetId) {
        var options = {
            url: urls.SAVE_AVATAR + '?type=' + type + '&assetId=' + assetId,
            callback: function (json) {
                if (json) {
                    alert('Saved');

                }
            }
        };

        app.makeRequest(options);
    };

})(window.app = window.app || {}, jQuery);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

野鹿林 2024-12-09 07:00:04

这个问题的全部内容如下: https://github.com/SteveSanderson/knockout/ issues/133

如果您可以在服务器上或 JavaScript 中强制代理 ID 为字符串(id + '' 有效),那么您将不会看到该问题。

另外,根据对代码的一些重组,这似乎在 1.3 中不再是问题。因此,您可能想尝试测试版: http://blog.stevensanderson.com/2011/08/31/knockout-1-3-0-beta-available/

This one has all the makings of this issue here: https://github.com/SteveSanderson/knockout/issues/133

If you can force your agent ids to strings either on the server or in JavaScript (id + '' works), then you will not see the issue.

Also, it appears that based on some reorganization of the code, this is no longer an issue in 1.3. So, you might want to try the beta out: http://blog.stevensanderson.com/2011/08/31/knockout-1-3-0-beta-available/

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文