Убегая из PrototypeJS .each () цикл

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

Я надеюсь, что этот ответ достаточно ясен для понимания людьми, и я ничего не пропустил.

Передача данных вперед

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

Для этого примера у нас будет ViewControllerA и ViewControllerB

Чтобы передать значение BOOL из ViewControllerA в ViewControllerB, мы сделаем следующее.

  1. в ViewControllerB.h создайте свойство для BOOL

    @property (nonatomic, assign) BOOL isSomethingEnabled;
    
  2. в ViewControllerA, вам нужно рассказать ему о ViewControllerB так используйте

    #import "ViewControllerB.h"
    

    Тогда, где вы хотите загрузить вид, например. didSelectRowAtIndex или еще что-нибудь IBAction, вам нужно установить свойство в ViewControllerB, прежде чем помещать его в стек навигации.

    ViewControllerB *viewControllerB = [[ViewControllerB alloc] initWithNib:@"ViewControllerB" bundle:nil];
    viewControllerB.isSomethingEnabled = YES;
    [self pushViewController:viewControllerB animated:YES];
    

    Это установит isSomethingEnabled в ViewControllerB в BOOL значение YES.

Передача данных с использованием сегментов

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

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender

. Таким образом, чтобы передать BOOL из ViewControllerA в ViewControllerB, мы бы сделайте следующее:

  1. в ViewControllerB.h создайте свойство для BOOL

    @property (nonatomic, assign) BOOL isSomethingEnabled;
    
  2. в ViewControllerA, которое вам нужно расскажите о ViewControllerB, поэтому используйте

    #import "ViewControllerB.h"
    
  3. Создайте переход от ViewControllerA до ViewControllerB на раскадровке и дайте ему идентификатор, в этом примере мы Я назову его "showDetailSegue"

  4. Далее нам нужно добавить метод к ViewControllerA, который вызывается при выполнении любого перехода, из-за этого нам нужно определить, какой вызов был вызван а затем сделай что-нибудь В нашем примере мы проверим "showDetailSegue", и если это будет выполнено, мы передадим наше значение BOOL в ViewControllerB

    -(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
        if([segue.identifier isEqualToString:@"showDetailSegue"]){
            ViewControllerB *controller = (ViewControllerB *)segue.destinationViewController;
            controller.isSomethingEnabled = YES;
        }
    }
    

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

    -(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
        if([segue.identifier isEqualToString:@"showDetailSegue"]){
            UINavigationController *navController = (UINavigationController *)segue.destinationViewController;
            ViewControllerB *controller = (ViewControllerB *)navController.topViewController;
            controller.isSomethingEnabled = YES;
        }
    }
    

    Это установит isSomethingEnabled в ViewControllerB значение BOOL YES.

Передача данных назад

Для передачи данных из ViewControllerB в ViewControllerA необходимо использовать Протоколы и делегаты или Блоки , последний может быть использован как слабосвязанный механизм для обратных вызовов.

Для этого мы сделаем ViewControllerA делегатом ViewControllerB. Это позволяет ViewControllerB отправлять сообщение обратно ViewControllerA, что позволяет нам отправлять данные обратно.

Чтобы ViewControllerA был делегатом ViewControllerB, он должен соответствовать протоколу ViewControllerB, который мы должны указать. Это сообщает ViewControllerA, какие методы он должен реализовать.

  1. В ViewControllerB.h ниже #import, но выше @interface вы указываете протокол.

    @class ViewControllerB;
    
    @protocol ViewControllerBDelegate 
    - (void)addItemViewController:(ViewControllerB *)controller didFinishEnteringItem:(NSString *)item;
    @end
    
  2. затем еще в ViewControllerB.h вам нужно установить свойство delegate и синтезировать в ViewControllerB.m

    @property (nonatomic, weak) id  delegate;
    
  3. В ViewControllerB мы вызываем сообщение на delegate, когда открываем контроллер представления.

    NSString *itemToPassBack = @"Pass this value back to ViewControllerA";
    [self.delegate addItemViewController:self didFinishEnteringItem:itemToPassBack];
    
  4. Вот и все для ViewControllerB. Теперь в ViewControllerA.h, скажите ViewControllerA импортировать ViewControllerB и соответствовать его протоколу.

    #import "ViewControllerB.h"
    
    @interface ViewControllerA : UIViewController 
    
  5. В ViewControllerA.m реализовать следующий метод из нашего протокола

    - (void)addItemViewController:(ViewControllerB *)controller didFinishEnteringItem:(NSString *)item
    {
        NSLog(@"This was returned from ViewControllerB %@",item);
    }
    
  6. Перед тем как отправить viewControllerB в стек навигации, нам нужно сообщить ViewControllerB, что ViewControllerA является его делегатом, в противном случае мы получим ошибку.

    ViewControllerB *viewControllerB = [[ViewControllerB alloc] initWithNib:@"ViewControllerB" bundle:nil];
    viewControllerB.delegate = self
    [[self navigationController] pushViewController:viewControllerB animated:YES];
    

Ссылки

  1. Использование делегирования для связи с другими контроллерами представления в Руководство по программированию контроллера представления ]
  2. Шаблон делегата

Центр уведомлений NSN Это еще один способ передачи данных.

// add observer in controller(s) where you want to receive data
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleDeepLinking:) name:@"handleDeepLinking" object:nil];

-(void) handleDeepLinking:(NSNotification *) notification {
    id someObject = notification.object // some custom object that was passed with notification fire.
}

// post notification
id someObject;
[NSNotificationCenter.defaultCenter postNotificationName:@"handleDeepLinking" object:someObject];

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

Блоки являются анонимными функциями.

Этот пример передает данные от Контроллера B к Контроллеру A

определяют блок

@property void(^selectedVoucherBlock)(NSString *); // in ContollerA.h

добавить обработчик блока (слушатель) , где вам нужно значение (например, вам нужен ваш ответ API в ControllerA или вам нужны данные ContorllerB на A)

// in ContollerA.m

- (void)viewDidLoad {
    [super viewDidLoad];
    __unsafe_unretained typeof(self) weakSelf = self;
    self.selectedVoucherBlock = ^(NSString *voucher) {
        weakSelf->someLabel.text = voucher;
    };
}

Перейти к контроллеру B

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
ControllerB *vc = [storyboard instantiateViewControllerWithIdentifier:@"ControllerB"];
vc.sourceVC = self;
    [self.navigationController pushViewController:vc animated:NO];

пожарный блок

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath: 
(NSIndexPath *)indexPath {
    NSString *voucher = vouchersArray[indexPath.row];
    if (sourceVC.selectVoucherBlock) {
        sourceVC.selectVoucherBlock(voucher);
    }
    [self.navigationController popToViewController:sourceVC animated:YES];
}

Другой рабочий пример для блоков

17
задан Mark Biek 25 June 2009 в 18:21
поделиться

4 ответа

if( val == 'bar' ) {
    throw $break;
}

It's documented at the same page you linked. It's an exception specially handled by the each function. When thrown, it prevents your function from being called on further elements.

33
ответ дан 30 November 2019 в 11:08
поделиться

Неправильный путь с той страницы, на которую вы перешли

 if(val == 'bar')
 {
    throw $break;
 }

?

2
ответ дан 30 November 2019 в 11:08
поделиться

Вы правы, и Prototype создал объект ( $ break ), который можно выбросить из каждой функции, чтобы включить эту функциональность. Согласно документации Prototype API:

Регулярные циклы могут быть сокращены в JavaScript с помощью операторов break и continue. Однако при использовании функций итератора ваш код выходит за рамки цикла: код цикла происходит за сценой.

Чтобы предоставить вам эквивалентную (хотя и менее оптимальную) функциональность, Prototype предоставляет два глобальных объекта исключения, $ break и $ продолжить. Их использование эквивалентно использованию соответствующего собственного оператора в ванильном цикле. Эти исключения должным образом перехватываются внутри каждого метода.

Также обратите внимание, что объект $ continue устарел,

2
ответ дан 30 November 2019 в 11:08
поделиться

верны, и Prototype создал объект ( $ break ), который можно выбросить из функции each, чтобы включить эту функциональность. Согласно документации Prototype API:

Обычные циклы могут быть сокращены в JavaScript с помощью операторов break и continue. Однако при использовании функций итератора ваш код выходит за рамки цикла: код цикла происходит за сценой.

Чтобы предоставить вам эквивалентную (хотя и менее оптимальную) функциональность, Prototype предоставляет два глобальных объекта исключения, $ break и $ продолжить. Их использование эквивалентно использованию соответствующего собственного оператора в ванильном цикле. Эти исключения должным образом перехватываются внутри каждого метода.

Также обратите внимание, что объект $ continue устарел, и для имитации оператора continue используйте вместо него обычный оператор return.

Пример кода:

var result = [];
$R(1,10).each(function(n) {
  if (0 == n % 2)
    return; // this equals continue
  if (n > 6)
    throw $break;
  result.push(n);
});
// result -> [1, 3, 5]

Подробнее о каждой функции можно прочитать здесь: http: //www.prototypejs. org / api / enumerable / each

7
ответ дан 30 November 2019 в 11:08
поделиться
Другие вопросы по тегам:

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