0

Я делаю расширение chrome и использует мало блоков текста. Я сделал класс, и каждый блок является экземпляром этого класса. Такой, что:JavaScript ООП и асинхронные методы из расширения Chrome api

function Block(bid){ 
    var block = Object.create(Block.prototype); 
    block.title = "Default" 
    block.content = ""; 
    block.bid = bid; 
    return block; 
}; 

Block.prototype.setTitle = function(){ 
    chrome.tabs.query({currentWindow: true, active: true}, function(tabs){ 
     this.title = tabs[0].title; 
    }); 
}; 

Моя проблема заключается в том, что, когда я называю SetTitle() на блоке объекта в заголовке свойство не изменяется с помощью метода; он остается в «По умолчанию». Я знаю, что это имеет какое-то отношение к синхронным и асинхронным методам, но я полностью проиграл об этом.

Любая помощь будет оценена!

+1

'this.title' означает свойство закрытия, а не' Block', из того, что я могу сказать. Проверьте, не связаны ли с этим вопросы, связанные с этим, что кажется. – Mjh

+0

@mjh Если бы я должен был делать 'Block.prototype.setTitle = function() {this.title =" New ";}' все работает отлично – commanderCool

+0

Да, потому что это '' '' '' '' 'принадлежит' Block.prototype.setTitle' , У вас есть два закрытия, а не один. Поэтому последнее закрытие 'this' должно быть ограничено, чтобы принадлежать внешнему. – Mjh

ответ

1

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

function Block(bid){ 
    var block = Object.create(Block.prototype); 
    block.title = "Default" 
    block.content = ""; 
    block.bid = bid; 
    return block; 
}; 

Block.prototype.setTitle = function(){ 

    var callback = function(tabs) { 
     this.title = tabs[0].title; 
    } 

    chrome.tabs.query({currentWindow: true, active: true}, callback.bind(this)); 
}; 
+0

большое спасибо! Я полностью забыл, что я входил в новую область при использовании 'chrome.tabs.query ...'. – commanderCool

+0

Без проблем, я рад, что это сработало :) – Mjh

0

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

function Block(bid){ 
    var block = Object.create(Block.prototype); 
    block.title = "Default" 
    block.content = ""; 
    block.bid = bid; 
    return block; 
}; 

Block.prototype.setTitle = function(){ 

    var self = this; // Get the reference to the instance 
    chrome.tabs.query({currentWindow: true, active: true}, function(tabs){ 
     self.title = tabs[0].title; 
    }); 
}; 
0

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

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

function Block(id) { 
    this.id = id; 
    this.title = 'Default'; 
    this.content = ''; 
} 

Block.prototype.setTitleByCurrentTab = function() { 
    chrome.tabs.query({currentWindow: true, active: true}, 
         this.setTitleByTab.bind(this)); 
} 

Block.prototype.setTitleByFirstTab = function(tabs) { 
    this.title = tabs[0].title; 
} 

Если иметь 2 метод, как представляется, накладные расходы, А последний один может быть преобразован в инкубаторе закрытие внутри, как это было предложен MJH.

Я просто хотел, чтобы выделить 2 вещи здесь:

  1. минимальный конструктор
  2. методы именование - setTitle() звучит как обычный сеттера, клиент может ожидать аргумент там, если он не знает (как-то) о реализации подробности
Смежные вопросы