powered by simpleCommunicator - 2.0.59     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / ASP.NET [игнор отключен] [закрыт для гостей] / Single page aplication
73 сообщений из 73, показаны все 3 страниц
Single page aplication
    #38933071
Lolka1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Парни, можете посоветовать какие-нибудь мануалы по изучению SPA?
Сам не разработчик, но тут приспичило кое-что напрогать..
...
Рейтинг: 0 / 0
Single page aplication
    #38933081
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SPA - это не технология - это концепция.

Так что надо определиться сначала, на чем планируется реализовывать, а потом уже мануалы выбирать.
...
Рейтинг: 0 / 0
Single page aplication
    #38933096
Lolka1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Shocker.Pro,

ASP.Net
...
Рейтинг: 0 / 0
Single page aplication
    #38933101
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ASP.Net WebForms? ASP.NET MVC?
...
Рейтинг: 0 / 0
Single page aplication
    #38933106
Lolka1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Shocker.Pro,

MVC
...
Рейтинг: 0 / 0
Single page aplication
    #38933120
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Single page aplication
    #38933123
Lolka1
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Shocker.Pro,

Большое спасибо, начну изучать
...
Рейтинг: 0 / 0
Single page aplication
    #38933139
petalvik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Single page aplication
    #38934005
Calabonga
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вот туториал по созданию своего собственного сайта на SPA
...
Рейтинг: 0 / 0
Single page aplication
    #38934008
Calabonga
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
...
Рейтинг: 0 / 0
Single page aplication
    #38934397
Фотография bured
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Calabonga
Что такое SPA или одностраничный портал

Breeze-то тут причём?
Кстати, он вроде бы тихо умер. По крайней мере, Джон Паппа - "папа" Бриза давно про него не вспоминает.
Человек только начинает, а вы ему втюхиваете свой венигрет всевозможных пакетов, непонятно зачем собранных вместе.
...
Рейтинг: 0 / 0
Single page aplication
    #38934399
Фотография bured
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lolka1Парни, можете посоветовать какие-нибудь мануалы по изучению SPA?
Сам не разработчик, но тут приспичило кое-что напрогать..
наверное тогда лучше почитать про KnockoutJS, он наиболее простой.
...
Рейтинг: 0 / 0
Single page aplication
    #38934407
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
buredLolka1Парни, можете посоветовать какие-нибудь мануалы по изучению SPA?
Сам не разработчик, но тут приспичило кое-что напрогать..
наверное тогда лучше почитать про KnockoutJS, он наиболее простой.

Какое отношение имеет KnockoutJS к SPA?
...
Рейтинг: 0 / 0
Single page aplication
    #38934408
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVosttburedпропущено...

наверное тогда лучше почитать про KnockoutJS, он наиболее простой.

Какое отношение имеет KnockoutJS к SPA?На нём можно нужно построить SPA-фреймворк. :-)
...
Рейтинг: 0 / 0
Single page aplication
    #38934411
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей КНа нём можно нужно построить SPA-фреймворк. :-)

Ну дык и на VanillaJS тоже можно.. ))

Роутинг?
Модули?
DI?
Фабрики?
Модели?
REST/API?
Контроллеры?
Костная архитектура?

Нифига нет. Называется, засучивай рукава и пили. Если же хочется сосредоточиться на решении задачи, а не написании очередного велосипеда, надо брать нормальный SPA-фреймфорк и не выёживаться
...
Рейтинг: 0 / 0
Single page aplication
    #38934412
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей К,

2-ой ангуляр, кстати, запилен на расовом тайпскрипте, советую присмотреться и выкинуть эти свои поигрушки детсадовские на нокауте
...
Рейтинг: 0 / 0
Single page aplication
    #38934414
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVosttАлексей КНа нём можно нужно построить SPA-фреймворк. :-)

Ну дык и на VanillaJS тоже можно.. ))

Роутинг?Что это? Зачем? Мне не надо.
hVosttМодули?AMD
hVosttDI?Мне не надо.
hVosttФабрики?Что это? Наверное, это есть в велосипеде.
hVosttМодели?Что это? Наверное, это есть в велосипеде.
hVosttREST/API?Да.
hVosttКонтроллеры?В последнем KO добавлен Component. Жаль, что поздно добавили, уже был написан свой велосипед.
hVosttКостная архитектура?Что за новая концепция?
hVosttНифига нет. Называется, засучивай рукава и пили.Ты программист, или где?
hVosttЕсли же хочется сосредоточиться на решении задачи, а не написании очередного велосипедаМне мой велосипед нравится больше.
hVosttнадо брать нормальный SPA-фреймфорк и не выёживаться Нормальных нет.
...
Рейтинг: 0 / 0
Single page aplication
    #38934468
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей КhVosttРоутинг?Что это? Зачем? Мне не надо.

Если ты не понимаешь что такое роутинг и зачем это надо, значит у тебя ещё нет опыта в разработке SPA.

Алексей КhVosttМодули?AMD

да, вижу что это есть.

Алексей КhVosttМодели?Что это? Наверное, это есть в велосипеде

получаешь данные, оборачиваешь во вью-модели? отправляешь, сериализуешь вью-модель в JSON?

Алексей КhVosttREST/API?Да.

не ври себе

Код: javascript
1.
2.
3.
4.
var data = /* Your data in JSON format - see below */;
$.post("/some/url", data, function(returnedData) {
    // This callback is executed if the post was successful     
})



Алексей КhVosttКостная архитектура?Что за новая концепция?

это значит, что тебе на надо думать над основной архитектурой, она уже есть из коробки. сразу пишешь модели, логику и шаблоны. не паришься как это всё организовать, даже структуру папок и файлов SPA фреймворк уже предусматривает.

для стороннего разработчика на типичной архитектуре фреймворка это означает возможность очень легко и быстро влиться в разработку, без вникания в дебри больной, безумной фантазии велосипедостроя (уж поверь мне, я ковырял твой Simple Solution Project, и самому ненавистному врагу не пожелаю поддерживать это или нечто подобное), а с фантазией обычно у авторов всё впорядке, не надо ни пить, ни курить, достаточно редактора кода

Алексей КТы программист, или где?

Я командный программист в первую очередь, для меня обеспечение комфортной разработки/сопровождения в команде в абсолютном приоритете. Что означает НЕТ велосипедам там, где можно обойтись без них. Чем меньше велосипедов, тем проще сопровождать и разрабатывать.

Алексей КНормальных нет.

У всех фатальный недостаток?
...
Рейтинг: 0 / 0
Single page aplication
    #38934503
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVosttАлексей Кпропущено...
Что это? Зачем? Мне не надо.

Если ты не понимаешь что такое роутинг и зачем это надо, значит у тебя ещё нет опыта в разработке SPA.Я не обязан знать все названия.
hVosttАлексей Кпропущено...
Что это? Наверное, это есть в велосипеде

получаешь данные, оборачиваешь во вью-модели? отправляешь, сериализуешь вью-модель в JSON?Всё что для этого нужно пишется за 5 минут.

hVosttэто значит, что тебе на надо думать над основной архитектурой, она уже есть из коробки. сразу пишешь модели, логику и шаблоны. не паришься как это всё организовать, даже структуру папок и файлов SPA фреймворк уже предусматривает.Да.

hVosttдля стороннего разработчика на типичной архитектуре фреймворка это означает возможность очень легко и быстро влиться в разработкуТам масштабы не те. Изучается за неделю в худшем случае. В отличие от ангуларов и прочих.

hVostt, без вникания в дебри больной, безумной фантазии велосипедостроя (уж поверь мне, я ковырял твой Simple Solution Project, и самому ненавистному врагу не пожелаю поддерживать это или нечто подобное),Если взялся критиковать, то нужны конкретные замечания. Общих слов не достаточно.

hVostt а с фантазией обычно у авторов всё впорядке, не надо ни пить, ни курить, достаточно редактора кода Согласен, фантазия у авторов всяких Prism-ов и ангуларов безгранична.

hVosttАлексей КТы программист, или где?

Я командный программист в первую очередь, для меня обеспечение комфортной разработки/сопровождения в команде в абсолютном приоритете. Что означает НЕТ велосипедам там, где можно обойтись без них. Чем меньше велосипедов, тем проще сопровождать и разрабатывать.Согласен, если в команде нет нормальных разработчиков, способных разработать инструмент "под себя", то да, велосипедами лучше не заниматься.

hVosttАлексей КНормальных нет.

У всех фатальный недостаток? Раньше не было, может теперь уже и есть, но мне уже не актуально.
...
Рейтинг: 0 / 0
Single page aplication
    #38934512
Фотография skyANA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей К, гы, захотелось взглянуть на твой код :)
...
Рейтинг: 0 / 0
Single page aplication
    #38934519
Фотография bured
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lolka1Сам не разработчик, но тут приспичило кое-что напрогать..

hVosttРоутинг?
Модули?
DI?
Фабрики?
Модели?
REST/API?
Контроллеры?
Костная архитектура?

Нифига нет. Называется, засучивай рукава и пили. Если же хочется сосредоточиться на решении задачи, а не написании очередного велосипеда, надо брать нормальный SPA-фреймфорк и не выёживаться
...
Рейтинг: 0 / 0
Single page aplication
    #38934536
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
skyANAАлексей К, гы, захотелось взглянуть на твой код :)
Пожалуйста
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
export = Index;
import Roles = require("CurrentUser/Roles");
import HomeIndex = require("Home/Index");
import FavoritesSelector = require("Favorites/FavoritesSelector");

class Index extends ssp.IndexForm {
    directions = new ssp.DataSource({ url: "api/MessageTaskApi/GetDirections" });
    categories = new ssp.DataSource({ url: "api/MessageTaskApi/GetCategories" });
    projects = new ssp.DataSource({ url: "api/MessageTaskApi/GetProjects" });
    states = new ssp.DataSource({ url: "api/MessageTaskApi/GetStates" });
    favorites = new ssp.DataSource({ url: "api/MessageTaskApi/GetFavorites" });
    roles = new Roles();
    table: ssp.Table;

    constructor(parameters?) {
        super({
            templateUrl: ssp.url.getViewUrl("MessageTask/Index"),
            indexApiController: "api/MessageTaskApi",
            excelApiController: "api/MessageTaskExcelApi",
            editApiController: "api/MessageTaskEditApi",
            getRowID: row => row.ID,
            getRowName: row => row.Subject,
            dataConverter: data => {
                $.each(data.PageRows || [], (i, row) => {
                    row.IsTaskNotReaded = ko.observable(row.IsTaskNotReaded);
                });
            },
            filterConverter: filter => {
                var p = parameters || {};

                if (p.notReaded) {
                    filter.FilterType(0); // Текущие задачи
                    filter.F0_Category(1); // Непрочитанные
                    filter.F0_Direction(0); // Все задачи                    
                }
            }
        });

        var columns = [
            new ssp.TableColumn({
                header: "Тема",
                cellClass: row => "taskContent",
                cellContentType: ssp.TableCellContentTypes.ContentModel,
                cellContent: row => {
                    var c = new ssp.Control({ templateName: "messageTask-index-taskContent-template" });
                    c["data"] = row;
                    c["parent"] = this;
                    return c;
                }                
            }),
            new ssp.TableColumn({
                header: "Дата",
                tooltip: "Дата постановки задачи или последнего комментария.",
                propertyName: "ActivityDate",
                formatter: ssp.formatters.dateTime,
                cellClass: row => "auto-width"
            }),
            new ssp.TableColumn({
                header: "Постановщик",
                cellClass: row => "auto-width",
                cellContentType: ssp.TableCellContentTypes.ContentModel,
                cellContent: row => {
                    var member = row.Sender;
                    return new ssp.Label(member.Name, member.IsMe ? ssp.Brands.Default : null);
                }
            }),
            new ssp.TableColumn({
                header: "Исполнитель",
                cellClass: row => "auto-width",
                cellContentType: ssp.TableCellContentTypes.ContentModel,
                cellContent: row => {
                    var member = row.Recipient;
                    return new ssp.Label(member.Name, member.IsMe ? ssp.Brands.Default : null);
                }
            }),
            new ssp.TableColumn({
                header: "Состояние",
                cellClass: row => "auto-width",
                cellContentType: ssp.TableCellContentTypes.ContentModel,
                cellContent: row => new ssp.Label(row.CurrentStateStr, row.IsActive ? ssp.Brands.Success : ssp.Brands.Default)
            }),
            new ssp.TableColumn({
                header: "Проект",
                propertyName: "ProjectStr"
            })
        ];

        $.each(columns, (i, column) => {
            column.canSort = false;
        });

        var contextMenu = new ssp.GroupMenuItem({
            template: ssp.groupMenuItemTemplates.button,
            items: [
                new ssp.UrlMenuItem({
                    header: "Подробно",
                    url: row => row ? this.getDetailUrl(row) : ""
                }),
                new ssp.FuncMenuItem({
                    header: row => row ? row.IsTaskNotReaded() ? "Пометить как прочтённое" : "Пометить как непрочтённое" : "",
                    func: row => { this.inverseIsTaskReaded(row); },
                    isEnabled: row => row && row.MustReadMessage
                }),
                new ssp.SeparatorMenuItem({
                    isVisible: () =>
                        this.roles.isInRole(this.roles.appRoles.message_task) ||
                        this.roles.isInRole(this.roles.appRoles.message_task_delete)
                }),
                new ssp.UrlMenuItem({
                    header: "Изменить",
                    url: row => row ? ssp.url.getDocUrl("MessageTask/Edit", { id: this.getRowID(row) }) : "",
                    isVisible: () => this.roles.isInRole(this.roles.appRoles.message_task),
                    isEnabled: row => row && row.CanChangeMessage
                }),
                new ssp.FuncMenuItem({
                    header: "Удалить",
                    func: row => { this.delete(row); },
                    isVisible: () => this.roles.isInRole(this.roles.appRoles.message_task_delete),
                    isEnabled: row => row && row.CanChangeMessage
                }),
                new ssp.SeparatorMenuItem(),
                new ssp.FuncMenuItem({
                    header: "Добавить в избранное",
                    func: row => { this.addToFavorite(row); }
                }),
                new ssp.FuncMenuItem({
                    header: "Удалить из избранного",
                    func: row => { this.deleteFromFavorite(row); },
                    isEnabled: () => {
                        var filter = this.filter.result();
                        return filter && filter.FilterType() == 1 /*Избранное*/ && filter.F1_FavID()
                    }
                })
            ]
        });

        this.table = new ssp.Table({
            addUrl: ssp.url.getDocUrl("MessageTask/Edit"),
            isAddVisible: () => this.roles.isInRole(this.roles.appRoles.message_task),
            dataSource: this.data,
            columns: columns,
            contextMenu: contextMenu
        });
    }

    getDetailUrl(row) {
        return ssp.url.getDocUrl("MessageTask/Detail", { id: row.ID });
    }

    inverseIsTaskReaded(row) {
        ssp.ajax
            .postJson("api/MessageApi/SetMessageReadedByID", { ID: this.getRowID(row), IsReaded: row.IsTaskNotReaded() })
            .done(() => {
                row.IsTaskNotReaded(!row.IsTaskNotReaded());
                HomeIndex.model.notReadedAlert.refresh();
                this.data.refreshImmediate();
            });
    }

    addToFavorite(row) {
        new FavoritesSelector()
            .select(selectedItem => {
                return ssp.ajax
                    .postJson("api/MessageTaskFavoritesApi/AddToFavorite", { TaskID: row.ID, FavID: selectedItem.ID })
                    .done(() => { this.data.refreshImmediate(); });
            });
    }

    deleteFromFavorite(row) {
        var favID = this.filter.result().F1_FavID();
        var favCaption = "";

        $.each(this.favorites.result() || [], (i, v) => {
            if (v.ID == favID) {
                favCaption = v.Caption;
                return false;
            }
        });

        var msg = "Задача будет исключена из категории избранного \"" + favCaption + "\". Продолжить?";

        ssp.commonDialogs
            .ask(msg)
            .done(() => {
                ssp.ajax
                    .postJson("api/MessageTaskFavoritesApi/DeleteFromFavorite", { TaskID: row.ID, FavID: favID })
                    .done(() => { this.data.refreshImmediate(); });
            });
    }
}

...
Рейтинг: 0 / 0
Single page aplication
    #38934539
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей КЯ не обязан знать все названия.

Нет конечно.

Алексей КТам масштабы не те. Изучается за неделю в худшем случае. В отличие от ангуларов и прочих.

Ну дык зачем ты советуешь людЯм заниматься велосепедостроительством? Человек, изучивший хорошо Ангуляр найдёт работу максимум на неделю, и ЗП будет не обижен. А знающий только нокаут, вообще сомневаюсь что хоть что-то найдёт... Такие знания нафиг никому не упёрлись.

Алексей КЕсли взялся критиковать, то нужны конкретные замечания. Общих слов не достаточно.

Я не критикую, я привожу пример того, что получается, когда одиночки делают свою архитектуру. Ты бы ещё больше слоёв там добавил, а то явно их недостаточно Это не критика, это факт, так оно обычно и получается.

Алексей КСогласен, фантазия у авторов всяких Prism-ов и ангуларов безгранична.

Ангуляр блетсящий пример, кстати. Вроде и команда дикая и поддержка гугловская и коммьюнити огромное, но на выходе, по крайне мере ветки 1.x получается весьма далёкая от идеала архитектура. Мне не нравится 1.x, очень много претензий. Но однако при всё при этом даже она в плюсе перед велосипедами в 95% случаев.

2.x ещё подробно не ковырял, но судя по поверхностному обзору, работа над ошибками была проведена существенная, похоже эта версия мне даже понравится.
...
Рейтинг: 0 / 0
Single page aplication
    #38934553
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVosttАлексей КТам масштабы не те. Изучается за неделю в худшем случае. В отличие от ангуларов и прочих.

Ну дык зачем ты советуешь людЯм заниматься велосепедостроительством?Я никому ничего не советую. Я делюсь своим мнением.
hVosttЧеловек, изучивший хорошо Ангуляр найдёт работу максимум на неделю, и ЗП будет не обижен.Ангулар будет изучен при необходимости максимум за неделю. Но зачем мне это?
hVosttА знающий только нокаут, вообще сомневаюсь что хоть что-то найдёт... Такие знания нафиг никому не упёрлись.Если контора отличает кандидатов по знанию "ангуларов", то её кадровая политика бездарна, делать в такой конторе нечего.
hVosttАлексей КЕсли взялся критиковать, то нужны конкретные замечания. Общих слов не достаточно.

Я не критикую, я привожу пример того, что получается, когда одиночки делают свою архитектуру.А меж тем эта архитектура прекрасно показала себя на практике. Да и архитектуры там как-таковой практически нет. Всё базируется на стандартной архитектуре приложений под WPF/WCF/EF, с некоторым расширениями.
hVosttТы бы ещё больше слоёв там добавил, а то явно их недостаточно Это не критика, это факт, так оно обычно и получается.Фактов не увидел.
hVosttАлексей КСогласен, фантазия у авторов всяких Prism-ов и ангуларов безгранична.

Ангуляр блетсящий пример, кстати. Вроде и команда дикая и поддержка гугловская и коммьюнити огромное, но на выходе, по крайне мере ветки 1.x получается весьма далёкая от идеала архитектура. Мне не нравится 1.x, очень много претензий. Но однако при всё при этом даже она в плюсе перед велосипедами в 95% случаев.

2.x ещё подробно не ковырял, но судя по поверхностному обзору, работа над ошибками была проведена существенная, похоже эта версия мне даже понравится.Через год будет версия 3.x, потом 4.x, наверняка без обратной совместимости. Потом всё успешно загнётся, когда у гугла появится новая игрушка.
...
Рейтинг: 0 / 0
Single page aplication
    #38934579
Фотография skyANA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей КskyANAАлексей К, гы, захотелось взглянуть на твой код :)
Пожалуйста
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
export = Index;
import Roles = require("CurrentUser/Roles");
import HomeIndex = require("Home/Index");
import FavoritesSelector = require("Favorites/FavoritesSelector");

class Index extends ssp.IndexForm {
    directions = new ssp.DataSource({ url: "api/MessageTaskApi/GetDirections" });
    categories = new ssp.DataSource({ url: "api/MessageTaskApi/GetCategories" });
    projects = new ssp.DataSource({ url: "api/MessageTaskApi/GetProjects" });
    states = new ssp.DataSource({ url: "api/MessageTaskApi/GetStates" });
    favorites = new ssp.DataSource({ url: "api/MessageTaskApi/GetFavorites" });
    roles = new Roles();
    table: ssp.Table;

    constructor(parameters?) {
        super({
            templateUrl: ssp.url.getViewUrl("MessageTask/Index"),
            indexApiController: "api/MessageTaskApi",
            excelApiController: "api/MessageTaskExcelApi",
            editApiController: "api/MessageTaskEditApi",
            getRowID: row => row.ID,
            getRowName: row => row.Subject,
            dataConverter: data => {
                $.each(data.PageRows || [], (i, row) => {
                    row.IsTaskNotReaded = ko.observable(row.IsTaskNotReaded);
                });
            },
            filterConverter: filter => {
                var p = parameters || {};

                if (p.notReaded) {
                    filter.FilterType(0); // Текущие задачи
                    filter.F0_Category(1); // Непрочитанные
                    filter.F0_Direction(0); // Все задачи                    
                }
            }
        });

        var columns = [
            new ssp.TableColumn({
                header: "Тема",
                cellClass: row => "taskContent",
                cellContentType: ssp.TableCellContentTypes.ContentModel,
                cellContent: row => {
                    var c = new ssp.Control({ templateName: "messageTask-index-taskContent-template" });
                    c["data"] = row;
                    c["parent"] = this;
                    return c;
                }                
            }),
            new ssp.TableColumn({
                header: "Дата",
                tooltip: "Дата постановки задачи или последнего комментария.",
                propertyName: "ActivityDate",
                formatter: ssp.formatters.dateTime,
                cellClass: row => "auto-width"
            }),
            new ssp.TableColumn({
                header: "Постановщик",
                cellClass: row => "auto-width",
                cellContentType: ssp.TableCellContentTypes.ContentModel,
                cellContent: row => {
                    var member = row.Sender;
                    return new ssp.Label(member.Name, member.IsMe ? ssp.Brands.Default : null);
                }
            }),
            new ssp.TableColumn({
                header: "Исполнитель",
                cellClass: row => "auto-width",
                cellContentType: ssp.TableCellContentTypes.ContentModel,
                cellContent: row => {
                    var member = row.Recipient;
                    return new ssp.Label(member.Name, member.IsMe ? ssp.Brands.Default : null);
                }
            }),
            new ssp.TableColumn({
                header: "Состояние",
                cellClass: row => "auto-width",
                cellContentType: ssp.TableCellContentTypes.ContentModel,
                cellContent: row => new ssp.Label(row.CurrentStateStr, row.IsActive ? ssp.Brands.Success : ssp.Brands.Default)
            }),
            new ssp.TableColumn({
                header: "Проект",
                propertyName: "ProjectStr"
            })
        ];

        $.each(columns, (i, column) => {
            column.canSort = false;
        });

        var contextMenu = new ssp.GroupMenuItem({
            template: ssp.groupMenuItemTemplates.button,
            items: [
                new ssp.UrlMenuItem({
                    header: "Подробно",
                    url: row => row ? this.getDetailUrl(row) : ""
                }),
                new ssp.FuncMenuItem({
                    header: row => row ? row.IsTaskNotReaded() ? "Пометить как прочтённое" : "Пометить как непрочтённое" : "",
                    func: row => { this.inverseIsTaskReaded(row); },
                    isEnabled: row => row && row.MustReadMessage
                }),
                new ssp.SeparatorMenuItem({
                    isVisible: () =>
                        this.roles.isInRole(this.roles.appRoles.message_task) ||
                        this.roles.isInRole(this.roles.appRoles.message_task_delete)
                }),
                new ssp.UrlMenuItem({
                    header: "Изменить",
                    url: row => row ? ssp.url.getDocUrl("MessageTask/Edit", { id: this.getRowID(row) }) : "",
                    isVisible: () => this.roles.isInRole(this.roles.appRoles.message_task),
                    isEnabled: row => row && row.CanChangeMessage
                }),
                new ssp.FuncMenuItem({
                    header: "Удалить",
                    func: row => { this.delete(row); },
                    isVisible: () => this.roles.isInRole(this.roles.appRoles.message_task_delete),
                    isEnabled: row => row && row.CanChangeMessage
                }),
                new ssp.SeparatorMenuItem(),
                new ssp.FuncMenuItem({
                    header: "Добавить в избранное",
                    func: row => { this.addToFavorite(row); }
                }),
                new ssp.FuncMenuItem({
                    header: "Удалить из избранного",
                    func: row => { this.deleteFromFavorite(row); },
                    isEnabled: () => {
                        var filter = this.filter.result();
                        return filter && filter.FilterType() == 1 /*Избранное*/ && filter.F1_FavID()
                    }
                })
            ]
        });

        this.table = new ssp.Table({
            addUrl: ssp.url.getDocUrl("MessageTask/Edit"),
            isAddVisible: () => this.roles.isInRole(this.roles.appRoles.message_task),
            dataSource: this.data,
            columns: columns,
            contextMenu: contextMenu
        });
    }

    getDetailUrl(row) {
        return ssp.url.getDocUrl("MessageTask/Detail", { id: row.ID });
    }

    inverseIsTaskReaded(row) {
        ssp.ajax
            .postJson("api/MessageApi/SetMessageReadedByID", { ID: this.getRowID(row), IsReaded: row.IsTaskNotReaded() })
            .done(() => {
                row.IsTaskNotReaded(!row.IsTaskNotReaded());
                HomeIndex.model.notReadedAlert.refresh();
                this.data.refreshImmediate();
            });
    }

    addToFavorite(row) {
        new FavoritesSelector()
            .select(selectedItem => {
                return ssp.ajax
                    .postJson("api/MessageTaskFavoritesApi/AddToFavorite", { TaskID: row.ID, FavID: selectedItem.ID })
                    .done(() => { this.data.refreshImmediate(); });
            });
    }

    deleteFromFavorite(row) {
        var favID = this.filter.result().F1_FavID();
        var favCaption = "";

        $.each(this.favorites.result() || [], (i, v) => {
            if (v.ID == favID) {
                favCaption = v.Caption;
                return false;
            }
        });

        var msg = "Задача будет исключена из категории избранного \"" + favCaption + "\". Продолжить?";

        ssp.commonDialogs
            .ask(msg)
            .done(() => {
                ssp.ajax
                    .postJson("api/MessageTaskFavoritesApi/DeleteFromFavorite", { TaskID: row.ID, FavID: favID })
                    .done(() => { this.data.refreshImmediate(); });
            });
    }
}

Очередной Smart UI.
...
Рейтинг: 0 / 0
Single page aplication
    #38934588
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
skyANAАлексей Кпропущено...
Пожалуйста
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
export = Index;
import Roles = require("CurrentUser/Roles");
import HomeIndex = require("Home/Index");
import FavoritesSelector = require("Favorites/FavoritesSelector");

class Index extends ssp.IndexForm {
    directions = new ssp.DataSource({ url: "api/MessageTaskApi/GetDirections" });
    categories = new ssp.DataSource({ url: "api/MessageTaskApi/GetCategories" });
    projects = new ssp.DataSource({ url: "api/MessageTaskApi/GetProjects" });
    states = new ssp.DataSource({ url: "api/MessageTaskApi/GetStates" });
    favorites = new ssp.DataSource({ url: "api/MessageTaskApi/GetFavorites" });
    roles = new Roles();
    table: ssp.Table;

    constructor(parameters?) {
        super({
            templateUrl: ssp.url.getViewUrl("MessageTask/Index"),
            indexApiController: "api/MessageTaskApi",
            excelApiController: "api/MessageTaskExcelApi",
            editApiController: "api/MessageTaskEditApi",
            getRowID: row => row.ID,
            getRowName: row => row.Subject,
            dataConverter: data => {
                $.each(data.PageRows || [], (i, row) => {
                    row.IsTaskNotReaded = ko.observable(row.IsTaskNotReaded);
                });
            },
            filterConverter: filter => {
                var p = parameters || {};

                if (p.notReaded) {
                    filter.FilterType(0); // Текущие задачи
                    filter.F0_Category(1); // Непрочитанные
                    filter.F0_Direction(0); // Все задачи                    
                }
            }
        });

        var columns = [
            new ssp.TableColumn({
                header: "Тема",
                cellClass: row => "taskContent",
                cellContentType: ssp.TableCellContentTypes.ContentModel,
                cellContent: row => {
                    var c = new ssp.Control({ templateName: "messageTask-index-taskContent-template" });
                    c["data"] = row;
                    c["parent"] = this;
                    return c;
                }                
            }),
            new ssp.TableColumn({
                header: "Дата",
                tooltip: "Дата постановки задачи или последнего комментария.",
                propertyName: "ActivityDate",
                formatter: ssp.formatters.dateTime,
                cellClass: row => "auto-width"
            }),
            new ssp.TableColumn({
                header: "Постановщик",
                cellClass: row => "auto-width",
                cellContentType: ssp.TableCellContentTypes.ContentModel,
                cellContent: row => {
                    var member = row.Sender;
                    return new ssp.Label(member.Name, member.IsMe ? ssp.Brands.Default : null);
                }
            }),
            new ssp.TableColumn({
                header: "Исполнитель",
                cellClass: row => "auto-width",
                cellContentType: ssp.TableCellContentTypes.ContentModel,
                cellContent: row => {
                    var member = row.Recipient;
                    return new ssp.Label(member.Name, member.IsMe ? ssp.Brands.Default : null);
                }
            }),
            new ssp.TableColumn({
                header: "Состояние",
                cellClass: row => "auto-width",
                cellContentType: ssp.TableCellContentTypes.ContentModel,
                cellContent: row => new ssp.Label(row.CurrentStateStr, row.IsActive ? ssp.Brands.Success : ssp.Brands.Default)
            }),
            new ssp.TableColumn({
                header: "Проект",
                propertyName: "ProjectStr"
            })
        ];

        $.each(columns, (i, column) => {
            column.canSort = false;
        });

        var contextMenu = new ssp.GroupMenuItem({
            template: ssp.groupMenuItemTemplates.button,
            items: [
                new ssp.UrlMenuItem({
                    header: "Подробно",
                    url: row => row ? this.getDetailUrl(row) : ""
                }),
                new ssp.FuncMenuItem({
                    header: row => row ? row.IsTaskNotReaded() ? "Пометить как прочтённое" : "Пометить как непрочтённое" : "",
                    func: row => { this.inverseIsTaskReaded(row); },
                    isEnabled: row => row && row.MustReadMessage
                }),
                new ssp.SeparatorMenuItem({
                    isVisible: () =>
                        this.roles.isInRole(this.roles.appRoles.message_task) ||
                        this.roles.isInRole(this.roles.appRoles.message_task_delete)
                }),
                new ssp.UrlMenuItem({
                    header: "Изменить",
                    url: row => row ? ssp.url.getDocUrl("MessageTask/Edit", { id: this.getRowID(row) }) : "",
                    isVisible: () => this.roles.isInRole(this.roles.appRoles.message_task),
                    isEnabled: row => row && row.CanChangeMessage
                }),
                new ssp.FuncMenuItem({
                    header: "Удалить",
                    func: row => { this.delete(row); },
                    isVisible: () => this.roles.isInRole(this.roles.appRoles.message_task_delete),
                    isEnabled: row => row && row.CanChangeMessage
                }),
                new ssp.SeparatorMenuItem(),
                new ssp.FuncMenuItem({
                    header: "Добавить в избранное",
                    func: row => { this.addToFavorite(row); }
                }),
                new ssp.FuncMenuItem({
                    header: "Удалить из избранного",
                    func: row => { this.deleteFromFavorite(row); },
                    isEnabled: () => {
                        var filter = this.filter.result();
                        return filter && filter.FilterType() == 1 /*Избранное*/ && filter.F1_FavID()
                    }
                })
            ]
        });

        this.table = new ssp.Table({
            addUrl: ssp.url.getDocUrl("MessageTask/Edit"),
            isAddVisible: () => this.roles.isInRole(this.roles.appRoles.message_task),
            dataSource: this.data,
            columns: columns,
            contextMenu: contextMenu
        });
    }

    getDetailUrl(row) {
        return ssp.url.getDocUrl("MessageTask/Detail", { id: row.ID });
    }

    inverseIsTaskReaded(row) {
        ssp.ajax
            .postJson("api/MessageApi/SetMessageReadedByID", { ID: this.getRowID(row), IsReaded: row.IsTaskNotReaded() })
            .done(() => {
                row.IsTaskNotReaded(!row.IsTaskNotReaded());
                HomeIndex.model.notReadedAlert.refresh();
                this.data.refreshImmediate();
            });
    }

    addToFavorite(row) {
        new FavoritesSelector()
            .select(selectedItem => {
                return ssp.ajax
                    .postJson("api/MessageTaskFavoritesApi/AddToFavorite", { TaskID: row.ID, FavID: selectedItem.ID })
                    .done(() => { this.data.refreshImmediate(); });
            });
    }

    deleteFromFavorite(row) {
        var favID = this.filter.result().F1_FavID();
        var favCaption = "";

        $.each(this.favorites.result() || [], (i, v) => {
            if (v.ID == favID) {
                favCaption = v.Caption;
                return false;
            }
        });

        var msg = "Задача будет исключена из категории избранного \"" + favCaption + "\". Продолжить?";

        ssp.commonDialogs
            .ask(msg)
            .done(() => {
                ssp.ajax
                    .postJson("api/MessageTaskFavoritesApi/DeleteFromFavorite", { TaskID: row.ID, FavID: favID })
                    .done(() => { this.data.refreshImmediate(); });
            });
    }
}

Очередной Smart UI.MVVM.
...
Рейтинг: 0 / 0
Single page aplication
    #38934594
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
зы: Всегда удивляли подобные взгляды на происходящее. Некоторые считают, что если разделить программу на XXX слоёв, то она автоматически станет лучше. Бред какой-то...
...
Рейтинг: 0 / 0
Single page aplication
    #38934607
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
skyANAОчередной Smart UI.

Тут лапша обыкновенная, Stupid Fat UI, всё перемешано и навалено в кучу, так примерно чуть продвинутые студенты свои лабы пишут.

Даже KnockoutJS не спасает, приходится лепить казюльки типа:

Код: javascript
1.
2.
3.
$.each(columns, (i, column) => {
            column.canSort = false;
        });



Какие уж там логика отдельно, представление отдельно... Единственно, есть зачатки декомпозиции (типы из ssp), но всё равно выглядит как жестокое издевательство, если планируется это сопровождать. Если ж это ПО с коротким циклом жизни и с одним пожизненным разрабом с безупречной памятью, то ОК, сойдёт и так
...
Рейтинг: 0 / 0
Single page aplication
    #38934608
Фотография skyANA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей КskyANAпропущено...
Очередной Smart UI.MVVM.На MVVM не тянет.
...
Рейтинг: 0 / 0
Single page aplication
    #38934610
Фотография skyANA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей Кзы: Всегда удивляли подобные взгляды на происходящее. Некоторые считают, что если разделить программу на XXX слоёв, то она автоматически станет лучше. Бред какой-то...Зачем на трёхзначное число слоёв?
...
Рейтинг: 0 / 0
Single page aplication
    #38934612
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей Кзы: Всегда удивляли подобные взгляды на происходящее. Некоторые считают, что если разделить программу на XXX слоёв, то она автоматически станет лучше. разделение нужно не для абстрактной лучшести, а для конкретного удобства совместной разработки и поддержки. да и индивидуальной тоже.
Алексей КБред какой-то...а статья действительно не фонтан.
...
Рейтинг: 0 / 0
Single page aplication
    #38934615
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей КMVVM.

не обманывай себя

такое тянет только на прототип, который оч. быстро накидали, чтобы хоть что-то быстренько показать. для ПО с длительным жизненным циклом такое УГ писать -- это преступление. но где-то на это закрывают глаза (или не открывают вовсе), содержат разрабов, которые совершенно наплевательски относятся к разработке. если такой разраб устаивает работодателя, которому скорее всего до фени чё там и как пишется, да хоть задницей, ну тогда и отличненько. нормальный жизнеспособный тандем
...
Рейтинг: 0 / 0
Single page aplication
    #38934618
Фотография skyANA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVosttЕсли ж это ПО с коротким циклом жизни и с одним пожизненным разрабом с безупречной памятью, то ОК, сойдёт и такУ них всегда будет 11 разработчиков. Никто не придёт и не уйдёт. Да и в остальном ничего меняться не будет. :) Давно же уже выяснили.
...
Рейтинг: 0 / 0
Single page aplication
    #38934634
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AntonariyАлексей Кзы: Всегда удивляли подобные взгляды на происходящее. Некоторые считают, что если разделить программу на XXX слоёв, то она автоматически станет лучше. разделение нужно не для абстрактной лучшести, а для конкретного удобства совместной разработки и поддержки. да и индивидуальной тоже.В данном конкретном случае, я бы добавил.

Программа разделена на функциональные модули, реализующие каждый свою предметную область. Нужно обязательно выработать стандарт, согласно которого будут оформляться функциональные модули, для упрощения их интеграции между собой. Например, в WPF удобно представлять модули в виде UserControl.

Внутри каждого модуля уже можно выделять различные системные слои (M, V, C, VM и т. п.), но по необходимости, чтобы не нарваться на недостаточную ответственность классов и лишнее делегирование.
...
Рейтинг: 0 / 0
Single page aplication
    #38934647
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVostt, skyANA

Не парьтесь, в таком ключе разговора у нас не получится.
...
Рейтинг: 0 / 0
Single page aplication
    #38934678
Фотография skyANA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей КhVostt, skyANA

Не парьтесь, в таком ключе разговора у нас не получится.Да никто и не парится.

Где у тебя разделение на M, V, C, и VM?
...
Рейтинг: 0 / 0
Single page aplication
    #38934682
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей КhVostt, skyANA

Не парьтесь, в таком ключе разговора у нас не получится.

А никто не парится. KnockoutJS не является SPA фреймворком, это факт. Однако его можно успешно использовать в качестве реализации MVVM для SPA, например, с использованием Backbone или даже своего фреймворка, тоже факт. Но у тебя это сделать таким образом не получается. Ну без надобности оно тебе, тоже выяснили, а убеждать или переубеждать никого в чём-то смысла нет.
...
Рейтинг: 0 / 0
Single page aplication
    #38934691
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVosttАлексей КhVostt, skyANA

Не парьтесь, в таком ключе разговора у нас не получится.

А никто не парится. KnockoutJS не является SPA фреймворком, это факт. Однако его можно успешно использовать в качестве реализации MVVM для SPA, например, с использованием Backbone или даже своего фреймворка, тоже факт. Да?!
...
Рейтинг: 0 / 0
Single page aplication
    #38934695
Фотография skyANA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей КВнутри каждого модуля уже можно выделять различные системные слои (M, V, C, VM и т. п.), но по необходимости, чтобы не нарваться на недостаточную ответственность классов и лишнее делегирование.То ты SRP придерживаться пытался, теперь вот про "недостаточную ответственность классов и лишнее делегирование" втирать начал.

Работу с сервером-то мог вынести в отдельный класс. Зачем представлению знать о том, что данные Ajax-ом запрашиваются по таким-то урлам?
Типа не достаточно отвечать только за UI? :)
...
Рейтинг: 0 / 0
Single page aplication
    #38934696
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
skyANAАлексей КhVostt, skyANA

Не парьтесь, в таком ключе разговора у нас не получится.Да никто и не парится.

Где у тебя разделение на M, V, C, и VM?Там же, где и у всех остальных.
...
Рейтинг: 0 / 0
Single page aplication
    #38934699
Фотография skyANA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей КskyANAпропущено...
Да никто и не парится.

Где у тебя разделение на M, V, C, и VM?Там же, где и у всех остальных.У всех остальных кого? Членов твоей команды?
...
Рейтинг: 0 / 0
Single page aplication
    #38934703
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
skyANAАлексей КВнутри каждого модуля уже можно выделять различные системные слои (M, V, C, VM и т. п.), но по необходимости, чтобы не нарваться на недостаточную ответственность классов и лишнее делегирование.То ты SRP придерживаться пытался, теперь вот про "недостаточную ответственность классов и лишнее делегирование" втирать начал.

Работу с сервером-то мог вынести в отдельный класс. Зачем представлению знать о том, что данные Ajax-ом запрашиваются по таким-то урлам?
Типа не достаточно отвечать только за UI? :)Это ViewModel, представление я не показывал, оно в HTML. Выносить обращения к серверу из ViewModel в отдельный класс в данном случае смысла не вижу.
...
Рейтинг: 0 / 0
Single page aplication
    #38934728
Фотография skyANA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей КskyANAпропущено...
То ты SRP придерживаться пытался, теперь вот про "недостаточную ответственность классов и лишнее делегирование" втирать начал.

Работу с сервером-то мог вынести в отдельный класс. Зачем представлению знать о том, что данные Ajax-ом запрашиваются по таким-то урлам?
Типа не достаточно отвечать только за UI? :)Это ViewModel, представление я не показывал.А на мой взгляд это и ViewModel и View. Вот же диалог показывается (представление):
Код: javascript
1.
2.
3.
var msg = "Задача будет исключена из категории избранного \"" + favCaption + "\". Продолжить?";

ssp.commonDialogs.ask(msg)


Ну и templateUrl я не понял, что такое. Как используется?

Алексей КВыносить обращения к серверу из ViewModel в отдельный класс в данном случае смысла не вижу.А чем же у тебя занимается Model?
...
Рейтинг: 0 / 0
Single page aplication
    #38934740
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей К Да?!

Ты сказал "на нём", что является очевидной глупостью. KnockoutJS никак не может быть основой для SPA, у него нет даже маршрутизации, а его самого надо инициализировать вручную как минимум через DOMContentLoaded событие. Так что не говори глупостей, вот и всё.
...
Рейтинг: 0 / 0
Single page aplication
    #38934755
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
skyANAАлексей Кпропущено...
Это ViewModel, представление я не показывал.А на мой взгляд это и ViewModel и View. Вот же диалог показывается (представление):
Код: javascript
1.
2.
3.
var msg = "Задача будет исключена из категории избранного \"" + favCaption + "\". Продолжить?";

ssp.commonDialogs.ask(msg)

Что мне мешает создать из ViewModel диалог? Используется "диалоговый" сервис commonDialogs, всё в лучших традициях.
skyANAНу и templateUrl я не понял, что такое. Как используется?URL откуда берётся HTML View.
skyANAАлексей КВыносить обращения к серверу из ViewModel в отдельный класс в данном случае смысла не вижу.А чем же у тебя занимается Model?Традиционно, модель хранит данные, получаемые с сервера. В примере их не видно.
...
Рейтинг: 0 / 0
Single page aplication
    #38934766
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVosttАлексей К Да?!

Ты сказал "на нём", что является очевидной глупостью. KnockoutJS никак не может быть основой для SPA, у него нет даже маршрутизации, а его самого надо инициализировать вручную как минимум через DOMContentLoaded событие. Так что не говори глупостей, вот и всё.Ну я понял, что ты тут самый самый специалист по SPA фреймворкам. Извини, что потревожил твои религиозные чувства.
...
Рейтинг: 0 / 0
Single page aplication
    #38934827
Фотография skyANA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей КskyANAпропущено...
А на мой взгляд это и ViewModel и View. Вот же диалог показывается (представление):
Код: javascript
1.
2.
3.
var msg = "Задача будет исключена из категории избранного \"" + favCaption + "\". Продолжить?";

ssp.commonDialogs.ask(msg)

Что мне мешает создать из ViewModel диалог? Используется "диалоговый" сервис commonDialogs, всё в лучших традициях.А, это сервис :) Понятно. Почему же ajax в отдельный сервис не вынесен "в лучших традициях"?
На фига ViewModel знать, откуда данные (локальные, или с сервера получены ajax-ом, или не ajax-ом)?
...
Рейтинг: 0 / 0
Single page aplication
    #38934828
Фотография skyANA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей К, и тексты следовало бы в ресурсы вынести, и урлы в config "в лучших традициях" :)
...
Рейтинг: 0 / 0
Single page aplication
    #38934840
Фотография skyANA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А вот кстати лучшие традиции Ajax calls относят к модели.
...
Рейтинг: 0 / 0
Single page aplication
    #38934862
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
skyANAАлексей К, и тексты следовало бы в ресурсы вынести, и урлы в config "в лучших традициях" :)Не хочу. :-)
skyANAА вот кстати лучшие традиции Ajax calls относят к модели.Как мне кажется, там описывается ViewModel - класс, к которому биндится View.

Но, как я и говорил выше, выделение классов произвожу по необходимости. На настоящий момент такой необходимости в данном проекте не вижу.
...
Рейтинг: 0 / 0
Single page aplication
    #38934868
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
skyANAАлексей Кпропущено...
Что мне мешает создать из ViewModel диалог? Используется "диалоговый" сервис commonDialogs, всё в лучших традициях.А, это сервис :) Понятно. Почему же ajax в отдельный сервис не вынесен "в лучших традициях"?
На фига ViewModel знать, откуда данные (локальные, или с сервера получены ajax-ом, или не ajax-ом)?Ну я не вижу в данном случае необходимости добавлять ещё одну абстракцию: писанины больше, пользы - ноль.

Но я не спорю, такое решение в других случаях может иметь право на жизнь.
...
Рейтинг: 0 / 0
Single page aplication
    #38934874
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
skyANAАлексей Кпропущено...
MVVM.На MVVM не тянет.Кстати по поводу "не тянет": если бы в данном коде велась работа непосредственно с HTML-элементами, тогда да, на MVVM бы это не тянуло. А тут тянет. :-)
...
Рейтинг: 0 / 0
Single page aplication
    #38934878
Фотография skyANA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей КskyANAА вот кстати лучшие традиции Ajax calls относят к модели.Как мне кажется, там описывается ViewModel - класс, к которому биндится View.Там описывается и model, и view model, и view.

Ajax calls относятся к model, ровно как и другие "operations in your business domain". А к view model относится "data and operations on a UI".
...
Рейтинг: 0 / 0
Single page aplication
    #38934902
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей КНу я понял, что ты тут самый самый специалист по SPA фреймворкам. Извини, что потревожил твои религиозные чувства.

Похоже, ты обиделся )
...
Рейтинг: 0 / 0
Single page aplication
    #38934920
Фотография skyANA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей КskyANAпропущено...
А, это сервис :) Понятно. Почему же ajax в отдельный сервис не вынесен "в лучших традициях"?
На фига ViewModel знать, откуда данные (локальные, или с сервера получены ajax-ом, или не ajax-ом)?Ну я не вижу в данном случае необходимости добавлять ещё одну абстракцию: писанины больше, пользы - ноль.

Но я не спорю, такое решение в других случаях может иметь право на жизнь."Keeping the view model abstract in this way lets it stay simple, so you can manage more sophisticated behaviors without getting lost".

Опять приходим к тому, что у тебя ничего никогда не меняется, не усложняется, не расширяется... :)
...
Рейтинг: 0 / 0
Single page aplication
    #38934927
Фотография skyANA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей КskyANAпропущено...
На MVVM не тянет.Кстати по поводу "не тянет": если бы в данном коде велась работа непосредственно с HTML-элементами, тогда да, на MVVM бы это не тянуло. А тут тянет. :-)view model ничего не должна знать о сервере и ajax, так же как и о HTML.
Так что пока не тянет :)
...
Рейтинг: 0 / 0
Single page aplication
    #38934952
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
skyANAАлексей Кпропущено...
Ну я не вижу в данном случае необходимости добавлять ещё одну абстракцию: писанины больше, пользы - ноль.

Но я не спорю, такое решение в других случаях может иметь право на жизнь."Keeping the view model abstract in this way lets it stay simple, so you can manage more sophisticated behaviors without getting lost".

Опять приходим к тому, что у тебя ничего никогда не меняется, не усложняется, не расширяется... :)Ну менять источник данных в данном случае мне точно не придётся.

По поводу изменений - чем больше абстракций, тем больше кода придётся менять при изменении предметной области, скорее всего в таком случае изменения коснуться всех слоёв.

skyANAАлексей Кпропущено...
Кстати по поводу "не тянет": если бы в данном коде велась работа непосредственно с HTML-элементами, тогда да, на MVVM бы это не тянуло. А тут тянет. :-)view model ничего не должна знать о сервере и ajax, так же как и о HTML.
Так что пока не тянет :)Если бы это был десктоп, то я бы согласился. Но для Веб AJAX является единственным способом взаимодействия с сервером, поэтому данная независимость нам ничего не даёт.
...
Рейтинг: 0 / 0
Single page aplication
    #38934965
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVosttАлексей КНу я понял, что ты тут самый самый специалист по SPA фреймворкам. Извини, что потревожил твои религиозные чувства.

Похоже, ты обиделся )Совсем нет. :-)
...
Рейтинг: 0 / 0
Single page aplication
    #38934969
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей КСовсем нет. :-)

ну слава Богу
...
Рейтинг: 0 / 0
Single page aplication
    #38934990
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей КПо поводу изменений - чем больше абстракций, тем больше кода придётся менять при изменении предметной области, скорее всего в таком случае изменения коснуться всех слоёв.

При чём тут "больше" абстракций? Ты так легко варьируешь этим понятием. Абстракций не надо ни больше, ни меньше, а ровно столько, чтобы решить простейшую задачу разделения ответственности. Не надо их лепить по принципу больше/меньше, много/мало. Есть определённые уровни, их всего 3: уровень изоляции модели, уровень вью-модели и уровень презентации. Чего ты там городишь, я не понимаю?

Кода как раз меньше придётся менять при изменении слоёв, так как у тебя полная, изолированная независимость. Хочешь наследуй контроллеры, вью-модели, фабрики, создавай изменяй их поведение, аггрегируй, выноси целые куски в отдельные компоненты (со строгим MVC-MVVM естественно).

Я работал с этим, это очень гибко и удобно. Никаких 100500 абстракций, которые ты тут навыдумывал. Не надо боятся абстракций, надо их применять.

Знаю, тебе не интересно, но ты бы всё же посмотрел на какой-нибудь популярный фреймворк, да пусть даже Ангуляр, хотя бы для общего развития. Неужели не интересно?
...
Рейтинг: 0 / 0
Single page aplication
    #38935005
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVosttАлексей КПо поводу изменений - чем больше абстракций, тем больше кода придётся менять при изменении предметной области, скорее всего в таком случае изменения коснуться всех слоёв.

При чём тут "больше" абстракций? Ты так легко варьируешь этим понятием. Абстракций не надо ни больше, ни меньше, а ровно столько, чтобы решить простейшую задачу разделения ответственности. Не надо их лепить по принципу больше/меньше, много/мало. Есть определённые уровни, их всего 3: уровень изоляции модели, уровень вью-модели и уровень презентации. Чего ты там городишь, я не понимаю?Ну представь, надо добавить поле в БД и форму редактирования, а у тебя данная сущность представлена разными классами в разных слоях: DAL, DTO и VM, свойство придётся добавлять в трёх классах вместо одного.
...
Рейтинг: 0 / 0
Single page aplication
    #38935031
Фотография skyANA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей КskyANAпропущено...
"Keeping the view model abstract in this way lets it stay simple, so you can manage more sophisticated behaviors without getting lost".

Опять приходим к тому, что у тебя ничего никогда не меняется, не усложняется, не расширяется... :)Ну менять источник данных в данном случае мне точно не придётся.

По поводу изменений - чем больше абстракций, тем больше кода придётся менять при изменении предметной области, скорее всего в таком случае изменения коснуться всех слоёв.Ну скорее всего всех. Но сделать это можно будет параллельно (совместная разработко, о которой уже упоминали).

А если например потребуется написать другую морду к этому же API? Мобильную к примеру и респонсив, и тоже на JavaScript?
Предметная область не изменилась, а изменения всё равно коснутся "всех слоёв" :)

Алексей КskyANAпропущено...
view model ничего не должна знать о сервере и ajax, так же как и о HTML.
Так что пока не тянет :)Если бы это был десктоп, то я бы согласился. Но для Веб AJAX является единственным способом взаимодействия с сервером, поэтому данная независимость нам ничего не даёт.Не единственным.

Плюс завтра попросят добавить поддержку offline режима и IndexedDB. Хотя это же опять не про тебя :)
...
Рейтинг: 0 / 0
Single page aplication
    #38935038
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей КНу представь, надо добавить поле в БД и форму редактирования, а у тебя данная сущность представлена разными классами в разных слоях: DAL, DTO и VM, свойство придётся добавлять в трёх классах вместо одного.

А вот и нет. Если ты добавишь поле, и у тебя не генерится форма на основе метамодели, которую легко можно запрашивать через тот же REST при желании, или без мета, тебе в любом случае надо добавить его в презентацию (в HTML), и этого в приницпе будет достаточно, так как вью-модель работает поверх модели, полученной из REST, ничего не поменяется, разве что если с этим полем не будет связана дополнительная логика, воможно слой валидации надо будет расширить. Но это в любом случае надо будет сделать, только тут изменения минимальны, практически ты трогаешь только то, что действительно надо изменить, а инфраструктуру не трогаешь, ничего не переколбашиваешь. Так как у каждого слоя чёткая область ответственности, прописывание всех полей поимённо в каждом слое обычно не требуется, ты наследуешь и агрегируешь, пользуешься метамоделью и...

и не описываешь набор колонок прямо в коде, как это сделано у тебя (очень, очень плохо).
...
Рейтинг: 0 / 0
Single page aplication
    #38935041
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
skyANAАлексей Кпропущено...
Ну менять источник данных в данном случае мне точно не придётся.

По поводу изменений - чем больше абстракций, тем больше кода придётся менять при изменении предметной области, скорее всего в таком случае изменения коснуться всех слоёв.Ну скорее всего всех. Но сделать это можно будет параллельно (совместная разработко, о которой уже упоминали).У нас контора маленькая, разработчики делятся по предметной области.
skyANAА если например потребуется написать другую морду к этому же API? Мобильную к примеру и респонсив, и тоже на JavaScript?
Предметная область не изменилась, а изменения всё равно коснутся "всех слоёв" :)А вот и нет. :-)

Мы обсуждаем клиентскую HTML+JS часть. Серверная WebAPI часть тут и так есть, она останется без изменений.
skyANAАлексей Кпропущено...
Если бы это был десктоп, то я бы согласился. Но для Веб AJAX является единственным способом взаимодействия с сервером, поэтому данная независимость нам ничего не даёт.Не единственным.

Плюс завтра попросят добавить поддержку offline режима и IndexedDB. Хотя это же опять не про тебя :)Да, это не про меня. :-)

Таких требований на настоящий момент у нас нет и не планируются.
...
Рейтинг: 0 / 0
Single page aplication
    #38935050
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVosttАлексей КНу представь, надо добавить поле в БД и форму редактирования, а у тебя данная сущность представлена разными классами в разных слоях: DAL, DTO и VM, свойство придётся добавлять в трёх классах вместо одного.

А вот и нет. Если ты добавишь поле, и у тебя не генерится форма на основе метамодели, которую легко можно запрашивать через тот же REST при желании, или без мета, тебе в любом случае надо добавить его в презентацию (в HTML), и этого в приницпе будет достаточно, так как вью-модель работает поверх модели, полученной из REST, ничего не поменяется, разве что если с этим полем не будет связана дополнительная логика, воможно слой валидации надо будет расширить. Но это в любом случае надо будет сделать, только тут изменения минимальны, практически ты трогаешь только то, что действительно надо изменить, а инфраструктуру не трогаешь, ничего не переколбашиваешь. Так как у каждого слоя чёткая область ответственности, прописывание всех полей поимённо в каждом слое обычно не требуется, ты наследуешь и агрегируешь, пользуешься метамоделью и...

и не описываешь набор колонок прямо в коде, как это сделано у тебя (очень, очень плохо).Я не сторонник генерации форм по метаданным.
...
Рейтинг: 0 / 0
Single page aplication
    #38935052
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей К,

Вот, кстати, совершенно свежий пример из опыта. В чужом проекте, которого до селе я в глаза не видел попросили добавить 2 поля и кнопку на форму (поле, чекбокс и кнопка), с логикой: если чекбокс нажат, поле разрешено изменять, если отжат поле запрещено изменять и оно очищается, кнопка работает только когда поле заполнено, и отправляет данные в REST.

Так как это Ангуляр, я чуть ли не с закрытыми глазами нашёл эту форму, так как у ангуляров структура типичная, без всяких больных фантазий, открыл HTML, добавил поля: два инпута и один баттон, прибиндил их, из REST эти поля уже приходят, и также уходят, ничего трогать не пришлось, и строчка в контроллер для логики UI (очищение значения text при изменении поля bool). Если надо, можно было бы в слой валидации добавить логику. Совершенно чётко всё разложено по феншую, никто никуда не лезет, контроллер вообще не знает как отправляются данные и куда, они просто сохраняются, а как отвечает модель, и модели пофиг что там сохраняется, она лишь принимает данные и отправляет, всё работает как часы, вся доработка заняла 25 минут вместе с доставанием проекта из репы и заливкой коммита. Чудеса!
...
Рейтинг: 0 / 0
Single page aplication
    #38935056
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей К,

А если бы в репо лежало нечто похожее на то, что ты привёл, я бы отказался от каких-либо действий, так как ХРЕН ЕГО ЗНАЕТ как это работает, как оно связано, и на что может повлиять любое изменение. Нафиг надо такое счастье, вот кто это УГ писал, тот пусть и разгребает его, как никак, это теперь незаменимый разработчик
...
Рейтинг: 0 / 0
Single page aplication
    #38935080
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVosttАлексей К,

Вот, кстати, совершенно свежий пример из опыта. В чужом проекте, которого до селе я в глаза не видел попросили добавить 2 поля и кнопку на форму (поле, чекбокс и кнопка), с логикой: если чекбокс нажат, поле разрешено изменять, если отжат поле запрещено изменять и оно очищается, кнопка работает только когда поле заполнено, и отправляет данные в REST.

Так как это Ангуляр, я чуть ли не с закрытыми глазами нашёл эту форму, так как у ангуляров структура типичная, без всяких больных фантазий, открыл HTML, добавил поля: два инпута и один баттон, прибиндил их, из REST эти поля уже приходят, и также уходят, ничего трогать не пришлось, и строчка в контроллер для логики UI (очищение значения text при изменении поля bool). Если надо, можно было бы в слой валидации добавить логику. Совершенно чётко всё разложено по феншую, никто никуда не лезет, контроллер вообще не знает как отправляются данные и куда, они просто сохраняются, а как отвечает модель, и модели пофиг что там сохраняется, она лишь принимает данные и отправляет, всё работает как часы, вся доработка заняла 25 минут вместе с доставанием проекта из репы и заливкой коммита. Чудеса!Ты не поверишь, в моём случае всё будет точно так же. :-)
...
Рейтинг: 0 / 0
Single page aplication
    #38935092
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей КТы не поверишь, в моём случае всё будет точно так же. :-)

ну а чего боишься тогда этих чёртовых обстракций?
...
Рейтинг: 0 / 0
Single page aplication
    #38935138
Фотография skyANA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей КskyANAпропущено...
Ну скорее всего всех. Но сделать это можно будет параллельно (совместная разработко, о которой уже упоминали).У нас контора маленькая, разработчики делятся по предметной области.
skyANAА если например потребуется написать другую морду к этому же API? Мобильную к примеру и респонсив, и тоже на JavaScript?
Предметная область не изменилась, а изменения всё равно коснутся "всех слоёв" :)А вот и нет. :-)

Мы обсуждаем клиентскую HTML+JS часть. Серверная WebAPI часть тут и так есть, она останется без изменений.Ты не понял.

В JS у нас есть model, которая инкапсулирует в себе все Ajax calls (IndexedDB calls, offline calls). Это набор js-"классов".
Я беру этот код и просто использую в другой HTML+JS морде без изменений.

А в твоём случае нужный код надо выдирать из view model и писать на его базе новую view model. Да и почему view model?
Новую морду может быстрее и проще реализовать используя другой MV* подход, не MVVM.

"Серверная WebAPI часть" в обоих случаях "тут и так есть, она останется без изменений".
...
Рейтинг: 0 / 0
Single page aplication
    #38935151
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
skyANAАлексей Кпропущено...
У нас контора маленькая, разработчики делятся по предметной области.
пропущено...
А вот и нет. :-)

Мы обсуждаем клиентскую HTML+JS часть. Серверная WebAPI часть тут и так есть, она останется без изменений.Ты не понял.

В JS у нас есть model, которая инкапсулирует в себе все Ajax calls (IndexedDB calls, offline calls). Это набор js-"классов".
Я беру этот код и просто использую в другой HTML+JS морде без изменений.Ок.
skyANAА в твоём случае нужный код надо выдирать из view model и писать на его базе новую view model.Да, если случится что-то невероятное, то придётся. Но чудес не бывает, невероятное не случится. :-)
...
Рейтинг: 0 / 0
Single page aplication
    #38935152
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVosttАлексей КТы не поверишь, в моём случае всё будет точно так же. :-)

ну а чего боишься тогда этих чёртовых обстракций? Я один раз нагородил абстракций, разгребал потом. Больше не хочу.
...
Рейтинг: 0 / 0
Single page aplication
    #38935299
Фотография skyANA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей КskyANAпропущено...
Ты не понял.

В JS у нас есть model, которая инкапсулирует в себе все Ajax calls (IndexedDB calls, offline calls). Это набор js-"классов".
Я беру этот код и просто использую в другой HTML+JS морде без изменений.Ок.
skyANAА в твоём случае нужный код надо выдирать из view model и писать на его базе новую view model.Да, если случится что-то невероятное, то придётся. Но чудес не бывает, невероятное не случится. :-)Помнится достаточно недавно за репозиторий спорили. Так что-то кроме SQL Server было для тебя невероятным :) Не зарекайся...
...
Рейтинг: 0 / 0
73 сообщений из 73, показаны все 3 страниц
Форумы / ASP.NET [игнор отключен] [закрыт для гостей] / Single page aplication
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]