2016-12-04 79 views
0

我是Javascript開發的初學者,我必須做古典的待辦應用程序。它必須是面向對象的,我的程序有兩個類:任務和標籤。 任務包含一些標籤。如何使用局部變量在其他地方寫監聽器函數?

當用戶點擊標籤時,他可以修改其名稱。首先,我寫了一個匿名回調函數,它正在監聽修改表單提交,並且運行良好。但是,我必須創建一個聲明的函數,而不是我現有的偵聽器。但是,我需要訪問我的對象的某些屬性(這是編輯),我完全不知道如何做這樣的事情。

這裏是我的代碼的一小部分:

module.Tag = class Tag { 
     constructor(name = 'untitled', parent = null) { 
      this.name = name; 
      this.parentTask = parent; 
     } 

     //Method which displays the tag name 
     display_name() { 
     return $('<li>').addClass('tag').text(this.name);  
     } 

     //Method which displays the tag 
     display() { 
     let tag_item = this.display_name(); 

     let field = $('<input>').prop('type', 'text').prop('value', this.name); 
     let button = $('<button>').addClass('validationButton').prop('type', 'submit').text('✓'); 
     let removeButton = $('<button>').addClass('removeButton').text('X'); 
     let form = $('<form>').append(field).append(button).append(removeButton); 
     let in_edit = false; 

     tag_item.click((event) => { 
      event.stopPropagation(); 
      event.preventDefault(); 

      let target = $(event.target); 

      if (target.is('li') && !in_edit) { 
      tag_item.empty(); 
      tag_item.append(form); 
      in_edit = true;   
      } 

      if (target.is('button') && target.prop('type') === 'submit') { 
      if(field.val() !== '') { 
       this.name = field.val(); 
       module.StorageManager.storeTasks(); 
      } 

      tag_item.empty(); 
      tag_item.text(this.name); 

      field.val(this.name); 

      in_edit = false; 
      } 

      if (target.is('button') && target.hasClass('removeButton')) { 
      if(confirm('Voulez-vous vraiment supprimer ce tag ?')) { 
       tag_item.remove(); 
       this.removeTagFromParent(); 

       module.StorageManager.storeTasks(); 
      } 
      } 
     }); 

     return tag_item; 
    } 

    //Method which removes the tag from the parent task 
    removeTagFromParent() { 
     this.parentTask.removeTag(this); 
    } 
    }; 

我的聽衆是在顯示方法,它使用Tag.name財產和一些在方法體中創建的變量。我看不到如何在其他地方編寫這個函數,而谷歌沒有幫助我。

我希望我的問題很清楚,英文不是我的母語。 一些建議?

+0

「*我要創建聲明別的地方,而不是我的聽衆現有的*命名函數」 - 爲什麼?使用可用的代碼。 – Bergi

+1

使用閉包。 – Bergi

+0

如果我的教授沒有要求我在其他地方執行特定功能,我會這樣做。另一個原因是我在我的代碼的另一部分有相同的監聽器,如果我找到解決問題的方法,我可以避免重複的代碼。 – LeGaulois88

回答

2

您可以提取您的anonymouse函數作爲另一個類方法。它是一個事件處理程序,所以爲了正確訪問定義的對象,您必須正確地綁定它。

下面是修改腳本的例子:

module.Tag = class Tag { 
     constructor(name = 'untitled', parent = null) { 
      this.name = name; 
      this.parentTask = parent; 
     } 

     //Method which displays the tag name 
     display_name() { 
     return $('<li>').addClass('tag').text(this.name);  
     } 

     //Method which displays the tag 
     display() { 
     let tag_item = this.display_name(); 

     let field = $('<input>').prop('type', 'text').prop('value', this.name); 
     let button = $('<button>').addClass('validationButton').prop('type', 'submit').text('✓'); 
     let removeButton = $('<button>').addClass('removeButton').text('X'); 
     let form = $('<form>').append(field).append(button).append(removeButton); 
     let in_edit = false; 

     tag_item.click(this.handleClick.bind(this)); // this is where you invoke the function and //bind it to the context of the class 

     return tag_item; 
    } 

    //Method which removes the tag from the parent task 
    removeTagFromParent() { 
     this.parentTask.removeTag(this); 
    } 

    // extracted method defined here: handleClick(event) { let tag_item = this.display_name(); let field = $('').prop('type', 'text').prop('value', this.name); event.stopPropagation(); event.preventDefault(); let target = $(event.target); if (target.is('li') && !in_edit) { tag_item.empty(); tag_item.append(form); in_edit = true; } if (target.is('button') && target.prop('type') === 'submit') { if(field.val() !== '') { this.name = field.val(); module.StorageManager.storeTasks(); } tag_item.empty(); tag_item.text(this.name); field.val(this.name); in_edit = false; } if (target.is('button') && target.hasClass('removeButton')) { if(confirm('Voulez-vous vraiment supprimer ce tag ?')) { tag_item.remove(); this.removeTagFromParent(); module.StorageManager.storeTasks(); } } } 
    };
+0

謝謝你的回答。另一個問題是我不得不在我的Tag類之外編寫函數,所以我無法訪問'this.name'或'this.display_name()'。 – LeGaulois88

+1

要在類外使用該函數,您需要在其外部提取名稱函數體「handclick」。然後,您必須修改該函數以接受參數,以處理標籤項目類的範圍或直接參數以接受tag_item和字段的值。 – Pineda

+0

非常感謝。它完美的工作! – LeGaulois88

相關問題