Что входит в “Контроллер” в “MVC”?

Код Бутани Виджая работает отлично. Для совместимости с IE 11 я использовал объект Blob, как показано ниже:

var tablesToExcel = (function() {
  var uri = 'data:application/vnd.ms-excel;base64,',
    tmplWorkbookXML = '<?xml version="1.0"?><?mso-application progid="Excel.Sheet"?><Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet" xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet">' +
    '<DocumentProperties xmlns="urn:schemas-microsoft-com:office:office"><Author>Axel Richter</Author><Created>{created}</Created></DocumentProperties>' +
    '<Styles>' +
    '<Style ss:ID="Currency"><NumberFormat ss:Format="Currency"></NumberFormat></Style>' +
    '<Style ss:ID="Date"><NumberFormat ss:Format="Medium Date"></NumberFormat></Style>' +
    '</Styles>' +
    '{worksheets}</Workbook>',
    tmplWorksheetXML = '<Worksheet ss:Name="{nameWS}"><Table>{rows}</Table></Worksheet>',
    tmplCellXML = '<Cell{attributeStyleID}{attributeFormula}><Data ss:Type="{nameType}">{data}</Data></Cell>',
    base64 = function(s) {
      return window.btoa(unescape(encodeURIComponent(s)))
    },
    format = function(s, c) {
      return s.replace(/{(\w+)}/g, function(m, p) {
        return c[p];
      })
    }
  return function(tables, wsnames, wbname, appname) {
    var ctx = "";
    var workbookXML = "";
    var worksheetsXML = "";
    var rowsXML = "";

    for (var i = 0; i < tables.length; i++) {
      if (!tables[i].nodeType) tables[i] = document.getElementById(tables[i]);
      for (var j = 0; j < tables[i].rows.length; j++) {
        rowsXML += '<Row>'
        for (var k = 0; k < tables[i].rows[j].cells.length; k++) {
          var dataType = tables[i].rows[j].cells[k].getAttribute("data-type");
          var dataStyle = tables[i].rows[j].cells[k].getAttribute("data-style");
          var dataValue = tables[i].rows[j].cells[k].getAttribute("data-value");
          dataValue = (dataValue) ? dataValue : tables[i].rows[j].cells[k].innerHTML;
          var dataFormula = tables[i].rows[j].cells[k].getAttribute("data-formula");
          dataFormula = (dataFormula) ? dataFormula : (appname == 'Calc' && dataType == 'DateTime') ? dataValue : null;
          ctx = {
            attributeStyleID: (dataStyle == 'Currency' || dataStyle == 'Date') ? ' ss:StyleID="' + dataStyle + '"' : '',
            nameType: (dataType == 'Number' || dataType == 'DateTime' || dataType == 'Boolean' || dataType == 'Error') ? dataType : 'String',
            data: (dataFormula) ? '' : dataValue,
            attributeFormula: (dataFormula) ? ' ss:Formula="' + dataFormula + '"' : ''
          };
          rowsXML += format(tmplCellXML, ctx);
        }
        rowsXML += '</Row>'
      }
      ctx = {
        rows: rowsXML,
        nameWS: wsnames[i] || 'Sheet' + i
      };
      worksheetsXML += format(tmplWorksheetXML, ctx);
      rowsXML = "";
    }

    ctx = {
      created: (new Date()).getTime(),
      worksheets: worksheetsXML
    };
    workbookXML = format(tmplWorkbookXML, ctx);

    var link = document.createElement("A");
    
    // IE 11
    if (window.navigator.msSaveBlob) {
      var blob = new Blob([workbookXML], {
        type: "application/csv;charset=utf-8;"
      });
      navigator.msSaveBlob(blob, 'test.xls');
    }
    // Chrome and other browsers
    else {
      link.href = uri + base64(workbookXML);
    }

    link.download = wbname || 'Workbook.xls';
    link.target = '_blank';
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
  }
})();
180
задан victor hugo 18 June 2009 в 13:06
поделиться

12 ответов

В предложенном вами примере вы правы: «пользователь нажал кнопку« удалить этот элемент »» в интерфейсе должен просто вызвать функцию «удалить» контроллера. Контроллер, однако, не знает, как выглядит представление, поэтому ваше представление должно собирать некоторую информацию, например, «какой элемент был нажат?»

В форме разговора:

View : «Привет , контроллер, пользователь только что сказал мне, что хочет удалить элемент 4. "
Контроллер :« Хм, проверив свои учетные данные, он может это сделать ... Привет, модель, я хочу, чтобы ты получил элемент 4 и сделайте все, что вы делаете, чтобы удалить его ».
Модель :« Пункт 4 ... получил. Он удален. Вернемся к вам, Контроллер. »
Контроллер :« Вот, я Соберу новый набор данных.

496
ответ дан 23 November 2019 в 06:11
поделиться

Вот хорошая статья по основам MVC.

В нем говорится ...

Контроллер - Контроллер переводит взаимодействия с видом в действия, которые должна выполнять модель.

Другими словами, ваша бизнес-логика. Контроллер реагирует на действия пользователя, предпринятые в представлении, и отвечает. Вы помещаете здесь проверку и выбираете соответствующее представление, если проверка не удалась или завершилась успешно (страница с ошибкой, окно сообщения и т. Д.).

Есть еще одна хорошая статья в Fowler .

23
ответ дан 23 November 2019 в 06:11
поделиться

С практической точки зрения я никогда не считал, что концепция контроллера особенно полезна. В моем коде я использую строгое разделение модели и представления, но четко определенного контроллера нет. Это кажется ненужной абстракцией.

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

10
ответ дан 23 November 2019 в 06:11
поделиться

Контроллер действительно является частью представления. Его задача - выяснить, какие службы необходимы для выполнения запроса, демаршалировать значения из представления в объекты, которые требуются интерфейсу службы, определять следующее представление и маршалировать ответ обратно в форму, которую может использовать следующее представление. . Он также обрабатывает любые создаваемые исключения и отображает их в представлениях, понятных пользователям.

Уровень обслуживания - это то, что знает варианты использования, единицы работы и объекты модели. Контроллер будет отличаться для каждого типа представления - у вас не будет одного и того же контроллера для настольных компьютеров, браузеров, Flex или мобильных интерфейсов. Я говорю, что это действительно часть пользовательского интерфейса.

Сервис-ориентированный: вот где и делается работа.

7
ответ дан 23 November 2019 в 06:11
поделиться

также обратите внимание, что каждый виджет Swing можно рассматривать как содержащий три компонента MVC: каждый имеет модель (т.е. ButtonModel), представление (BasicButtonUI) и элемент управления (сам JButton).

1
ответ дан 23 November 2019 в 06:11
поделиться

Here is a rule of thumb that I use: if it is a procedure that I will be using specifically for an action on this page, it belongs in the controller, not the model. The model should provide only a coherent abstraction to the data storage.

I've come up with this after working with a large-ish webapp written by developers who thought they were understood MVC but really didn't. Their "controllers" are reduced to eight lines of calling static class methods that are usuall called nowhere else :-/ making their models little more than ways of creating namespaces. Refactoring this properly does three things: shifts all the SQL into the data access layer (aka model), makes the controller code a bit more verbose but a lot more understandable, and reduces the old "model" files to nothing. :-)

3
ответ дан 23 November 2019 в 06:11
поделиться

На основании вашего вопроса , У меня сложилось впечатление, что вы немного не уверены в роли Модели. Модель привязана к данным, связанным с приложением; если у приложения есть база данных, работа модели будет с ней разговаривать. Он также будет обрабатывать любую простую логику, связанную с этими данными; если у вас есть правило, которое говорит, что для всех случаев, когда TABLE.foo == "Ура!" и TABLE.bar == "Ура!" затем установите TABLE.field = "W00t!", тогда вы хотите, чтобы Модель позаботилась об этом.

Контроллер - это то, что должно обрабатывать основную часть приложения ' s поведение. Итак, чтобы ответить на ваши вопросы:

«Могу ли я поместить public void actionPerformed (ActionEvent e) в представление с помощью простого вызова метода в контроллере?»

Я бы сказал нет. Я бы сказал, что это должно жить в контроллере; Представление должно просто передавать данные, поступающие из пользовательского интерфейса, в Контроллер, и позволять Контроллеру решать, какие методы следует вызывать в ответ.

«Если да, должна ли какая-либо проверка и т. д. выполняться в Контроллере?»

Основная часть вашей проверки действительно должна выполняться Контроллером; он должен ответить на вопрос, действительны ли данные, и если это не так, передать соответствующие сообщения об ошибках в представление. На практике вы можете включить несколько простых проверок работоспособности в слой просмотра для улучшения взаимодействия с пользователем. (Я' Я думаю, в первую очередь о веб-средах, где вы можете захотеть, чтобы в тот момент, когда пользователь нажимает «Отправить», выскакивает сообщение об ошибке, а не ждать всего цикла отправки -> процесс -> загрузки страницы, прежде чем сообщать им, что они облажались.) Просто быть осторожен; вы не хотите дублировать усилия больше, чем нужно, и во многих средах (опять же, я имею в виду Интернет) вам часто приходится рассматривать любые данные, поступающие из пользовательского интерфейса, как пакет грязных грязных лжет до тех пор, пока вы не подтвердите, что это действительно законно.

«Если да, как мне отправить сообщения об ошибках обратно в представление - должны ли они снова проходить через Модель или Контроллер должен просто отправлять их обратно в представление?»

У вас должен быть установлен какой-то протокол там, где View не Не обязательно знать, что будет дальше, пока Контроллер не сообщит об этом. Какой экран вы показываете им после того, как пользователь нажимает на эту кнопку? Представление может не знать, и Контроллер тоже может не знать, пока не посмотрит только что полученные данные. Это может быть «Перейти к этому другому экрану, как и ожидалось» или «Оставаться на этом экране и отображать это сообщение об ошибке».

По моему опыту, прямая связь между моделью и видом должна быть очень, очень ограничена и Представление не должно напрямую изменять какие-либо данные Модели; это должно быть задачей Контроллера.

«Если проверка выполняется в Представлении, что мне помещать в Контроллер?»

См. выше; настоящая проверка должна быть в контроллере. И, надеюсь, вы уже имеете некоторое представление о том, что нужно добавить в контроллер. : -)

Это ' Стоит отметить, что все это может получиться немного размытым по краям; как и в случае с любым таким сложным, как программная инженерия, требованием суждения будет множество. Просто руководствуйтесь здравым смыслом, старайтесь оставаться последовательными в рамках этого приложения и попробуйте применить полученные уроки в следующем проекте.

9
ответ дан 23 November 2019 в 06:11
поделиться

По сути, вы правы насчет того, что вы вставили в контроллер. Это единственный способ взаимодействия модели с представлением. Выполненное действие может быть помещено в представление, но фактическая функциональность может быть помещена в другой класс, который будет действовать как контроллер. Если вы собираетесь это сделать, я рекомендую изучить шаблон Command, который представляет собой способ абстрагирования всех команд, имеющих один и тот же приемник. Извините за отступление.

В любом случае, правильная реализация MVC будет иметь только следующие взаимодействия: Модель -> Просмотр Вид -> Контроллер Контроллер -> Представление

Единственное место, где может произойти другое взаимодействие, - это если вы используете наблюдателя для обновления представления, тогда представление должно будет запросить у контроллера необходимую информацию.

1
ответ дан 23 November 2019 в 06:11
поделиться

Насколько я понимаю, Контроллер переводит из действия пользовательского интерфейса к действиям уровня приложения. Например, в видеоигре Контроллер может переводить «переместил мышь на такое-то количество пикселей» в «хочет смотреть в таком-то и таком-то направлении». В приложении CRUD перевод может быть «нажатие на такую-то кнопку», чтобы «напечатать это», но концепция та же.

0
ответ дан 23 November 2019 в 06:11
поделиться

Проблема с MVC заключается в том, что люди думают, что представление, контроллер и модель должны быть как можно более независимыми друг от друга. Это не так - представление и контроллер часто взаимосвязаны - воспринимайте это как M (VC) .

Контроллер - это механизм ввода пользовательского интерфейса, который часто запутывается в представлении, особенно с графическим интерфейсом. Тем не менее, представление - это вывод, а контроллер - ввод. Представление часто может работать без соответствующего контроллера, но контроллер обычно гораздо менее полезен без представления. Удобные для пользователя контроллеры используют представление для более значимой и интуитивной интерпретации ввода пользователя. Это то, что затрудняет отделение концепции контроллера от представления.

Представьте себе радиоуправляемого робота на поле обнаружения в запечатанном ящике как модель.

Модель полностью посвящена состояниям и переходам между состояниями без концепции вывода (отображения) или того, что запускает переходы между состояниями. Я могу получить положение робота на поле, и робот знает, как изменить положение (сделать шаг вперед / назад / влево / вправо. Легко представить без представления или контроллера, но ничего полезного не делает

Подумайте о представлении без контроллера, например, кто-то в другой комнате в сети в другой комнате наблюдает за положением робота в виде координат (x, y), текущих вниз по прокручиваемой консоли. Это представление просто отображает состояние модели, но у этого парня нет контроллера Опять же, легко представить себе это представление без контроллера.

Подумайте о контроллере без представления, например, кто-то заперт в туалете с радиоконтроллером, настроенным на частоту робота. Этот контроллер отправляет входные данные и вызывает переходы между состояниями, не имея представления о том, что они делают с моделью (если что-либо). Легко представить, но бесполезно без какой-либо обратной связи с представлением.

Наиболее удобный пользовательский интерфейс координирует представление с контроллером, чтобы обеспечить более интуитивно понятный пользовательский интерфейс. Например, представьте себе вид / контроллер с сенсорным экраном, показывающий текущее положение робота в 2-D и позволяющий пользователю прикоснуться к точке на экране, которая оказывается перед роботом. Контроллеру нужны подробные данные о представлении, например, положение и масштаб области просмотра, а также положение точки касания в пикселях относительно положения пикселя робота на экране, чтобы интерпретировать это правильно (в отличие от парня, запертого в шкафу с радиоконтроллер).

Я уже ответил на ваш вопрос? : -)

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

... если какая-либо проверка и т. Д. Будет так что это нормально, если граница между ними нечеткая, то есть представление и контроллер как отдельные пакеты могут быть не так четко разделены, как хотелось бы, но это нормально. Возможно, вам придется принять, что контроллер не будет четко отделен от представления, поскольку представление от модели.

... если какая-либо проверка и т. Д. Будет так что это нормально, если граница между ними нечеткая, то есть представление и контроллер как отдельные пакеты могут быть не так четко разделены, как хотелось бы, но это нормально. Возможно, вам придется принять, что контроллер не будет четко отделен от представления, поскольку представление от модели.

... если какая-либо проверка и т. Д. Будет сделано в Контроллере? Если да, то как Я отправляю сообщения об ошибках обратно в Просмотр - если это проходит Модель снова, или Контроллер должен просто отправить его обратно в View?

Если проверка выполняется в View, что мне добавить в Контроллер?

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

Решающим испытанием для этого является вопрос: должен ли независимый наблюдатель (например, парень в другой комнате, наблюдающий за позицией робота через сеть) что-либо видеть или нет в результате чьей-то ошибки проверки (например, парень в туалете пытался приказать роботу сойти с поля). Обычно ответ отрицательный - ошибка проверки предотвратила переход состояния. Если состояния не было (робот не двигался), другие взгляды рассказывать незачем. Парень в шкафу просто не получил никакой обратной связи, что он пытался вызвать незаконный переход (без просмотра - плохой пользовательский интерфейс), и никому больше не нужно об этом знать.

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

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

65
ответ дан 23 November 2019 в 06:11
поделиться

Контроллер предназначен в первую очередь для совместной работы. -согласование между видом и моделью.

К сожалению, иногда он смешивается с представлением - в небольших приложениях это не так уж и плохо.

Я предлагаю вам поместить:

public void actionPerformed(ActionEvent e)

в контроллер. Затем ваш слушатель действий в вашем представлении должен делегировать контроллеру.

Что касается части проверки, вы можете поместить ее в представление или контроллер, я лично думаю, что он принадлежит контроллеру.

Я определенно рекомендую взять взгляните на Passive View и Supervising Presenter (который, по сути, разделен на Model View Presenter - по крайней мере, Фаулером). См .:

http://www.martinfowler.com/eaaDev/PassiveScreen.html

http://www.martinfowler.com/eaaDev/SupervisingPresenter.html

3
ответ дан 23 November 2019 в 06:11
поделиться

Шаблон MVC просто хочет, чтобы вы отделили представление (= представление) от бизнес-логики (= модель). Часть контроллера предназначена только для того, чтобы вызвать путаницу.

17
ответ дан 23 November 2019 в 06:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: