Как скрыть данные от одного контроллера, но поделиться ими с другим контроллером с помощью общей службы

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

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

  • ModalController - принимает ввод от пользователя
  • MyService — принимает ввод от пользователя и сохраняет его в массиве —
  • ActionController — имеет ссылку на массив MyService и отображает его в представлении

Выше приведена базовая структура приложения.

Вот это jsfiddle


person Courtney    schedule 24.04.2017    source источник
comment
Пожалуйста, предоставьте фактический код того, что вы пытаетесь сделать. Описание кода никогда не работает. Непонятно, что означают «скрыть» и «защитить». От кого вы «защищаете» эти данные и почему?   -  person Estus Flask    schedule 25.04.2017
comment
Извините, я добавил jsfiddle к отредактированному вопросу. Мне интересно, есть ли способ предотвратить доступ ModalCtrl к массиву.   -  person Courtney    schedule 25.04.2017
comment
На самом деле не существует понятия «защита» в том смысле, в каком вы его имеете в виду. В Javascript нет приватных переменных. Вещи скрыты только контекстом. Если вы не хотите, чтобы ваш контроллер обращался к массиву... просто не обращайтесь к массиву в этом контроллере.   -  person Pop-A-Stash    schedule 25.04.2017
comment
Как сказано выше, нет никакого способа сделать это, и я не могу придумать вескую причину для этого. Объяснение, почему вам нужно это сделать в первую очередь, поможет. Что будет, если вы не помешаете контроллеру? Поскольку у службы есть общедоступный интерфейс, любой контроллер или что-то еще может использовать passChore. Вы можете создать другую службу с ограниченной функциональностью, которая обертывает эту и не предоставляет метод passChore... но зачем?   -  person Estus Flask    schedule 25.04.2017
comment
Мне просто интересно. Не то, чем я хочу заниматься. Рассмотрение таких концепций, как инкапсуляция и сокрытие данных. Я подумал, что, поскольку ModalCtrl не нуждается в доступе к массиву, было бы неплохо запретить ему доступ к массиву.   -  person Courtney    schedule 25.04.2017


Ответы (1)


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

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

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

С другой стороны, TypeScript предназначен для расширения JavaScript с помощью типов и контроля доступа, поэтому его можно решить таким образом, по крайней мере, во время разработки (до того, как исходный код TS был скомпилирован в JS):

interface IWritableFooService {
    setFoo();
}

interface IDuplexFooService extends IWritableFooService {
    getFoo();
}

class FooService implements IDuplexFooService {
    getFoo() {...}
    setFoo() {...}
}

Учитывая, что услуга определяется как

app.service('fooService', FooService);

Его можно вводить в одно место с ограничительным типом:

app.controller('BarController', function (fooService: IWritableFooService) {...});

И рассыпным шрифтом в другом:

app.controller('BazController', function (fooService: IDuplexFooService) {...});

Если BarController попытается использовать fooService.getFoo(), это приведет к ошибке компиляции TypeScript.

Такой подход является примером чрезмерной инженерии. Даже если был указан правильный интерфейс, никто не может запретить разработчику заменить IWritableFooService на тип IDuplexFooService в какой-то момент. Лучшие практики ООП исходят из практических соображений, и, похоже, их нет. Но да, это можно сделать с помощью TypeScript.

person Estus Flask    schedule 25.04.2017