2013-04-26 26 views
5

Trong ứng dụng của tôi có phần động được tải từ cơ sở dữ liệu như chuỗi trông giống như:RequireJS nạp chuỗi

"define(['dependency1', 'dependency2'], function(){"+ 
" // function body" + 
"})" 

mà chỉ là một mô-đun requireJS đơn giản, như một chuỗi. Tôi muốn tải xuống kịch bản ở trên bằng cách sử dụng async yêu cầu cuộc gọi. Vì vậy, kịch bản requireJS chính của tôi trông giống như:

require(["jquery"], function($){   
    $(document).ready(function(){ 
     // logic to load specific script from database 
     var scriptString = functionToLoadTheStringAbove(); 

     // ideally i would like to call it like this    
     require([scriptString], function(){ 
      // scriptString, dependency1, dependency2 are loaded 
     } 
    }); 
}); 

Làm cách nào để tải các chuỗi đó trong requireJS? Tôi biết về plugin văn bản, nhưng nó chỉ cho phép tải từ các tập tin. Tôi đã thử eval nhưng nó không giải quyết phụ thuộc một cách chính xác.

+0

hãy rõ ràng trong khi yêu cầu bất kỳ câu hỏi. Vui lòng refeame câu hỏi của bạn. –

+0

Ồ, tôi có thực sự lưu trữ mã đánh giá trong cơ sở dữ liệu như thế này không? –

+0

Có. Trong trường hợp của tôi, nó nằm trong phần mở rộng của trình duyệt. Vì vậy, không có sự lựa chọn của việc tạo ra các điểm cuối REST/lưu mã động trong hệ thống tập tin. – bradnoriega

Trả lời

5

này là khá muộn, nhưng tôi chỉ đăng giải pháp của tôi ở đây trong trường hợp bất cứ ai cần.

Vì vậy, tôi đã yêu cầu diễn đàn requireJS và kiểm tra nguồn của text! pluginjson! plugin. Cách tốt nhất để tải mô-đun từ Chuỗi trong RequireJS là bằng cách tạo plugin của riêng bạn để tải Chuỗi, sau đó sử dụng onLoad.fromText() sẽ eval Chuỗi của bạn và giải quyết tất cả các phụ thuộc.

Ví dụ plugin của tôi (chúng ta hãy gọi nó db! plugin):

define([], function(){ 
    var db = new Database(); // string is loaded from LocalStorage 
    return { 
     load: function(name, req, onLoad, reqConfig){ 
      db.get(name, function(err, scriptString){ 
       if (err) onLoad(err); 
       else onLoad.fromText(scriptString); 
      }); 
     } 
    } 
}); 

Sau đó, bạn có thể sử dụng các plugin như:

require(["jquery", "db!myScript"], function($, myScript){   
    // jQuery, myScript and its dependencies are loaded from database 
}); 

Lưu ý:

  1. Không có đường đến require() từ chuỗi không có eval. Đây là nội dung onLoad.fromText() thực hiện nội bộ. Vì eval là ác, bạn chỉ nên sử dụng nó nếu bạn biết String bạn đang truy cập eval(). Nếu bạn đang sử dụng nó trong phần mở rộng của trình duyệt, bạn có thể muốn thư giãn chính sách CSP.
  2. Để đặt tên cho mô-đun Chuỗi, bạn có thể sử dụng explicit naming syntax. Bằng cách này, mô-đun của bạn sẽ luôn có cùng tên tuyệt đối.
-1

Bạn sẽ có thể làm:

require(["jquery"], function($){   
    $(document).ready(function(){ 
     // logic to load specific script from database 
     var scriptString = functionToLoadTheStringAbove(); 

     var olddefine = define; // require js define 
     var runme; // capture function 
     define = function (args,func){ 
      runme = func; 
     } 
     eval(scriptString); 
     runme(); // run the function in current scope 
     define = olddefine; // restore requirejs function 

     // dependency1, dependency2 are loaded   
    }); 
}); 
+2

Nó không hoạt động. chạy runme() chỉ không giải quyết các phụ thuộc + chúng ta mất phạm vi/đóng được cung cấp bởi yêu cầu. – bradnoriega

0

Để trả lời câu hỏi trực tiếp nhiều hơn một chút, tạo một plugin như vậy:

define("load-string",[], function(){ 
    var strings=[], 
     re_package_name = /^string_module_(\d+)$/; 
    return { 
     normalize: function(name, _){ 
      if(re_package_name.test(name)){ 
       return name 
      } 
      var nml = "string_module_" + (strings.push(name)-1); 
      return nml; 
     }, 
     load: function(name, _, onLoad, config){ 
      if(re_package_name.test(name)){ 
       onLoad.fromText(strings[name.match(re_package_name)[1]]); 
      }else{ 
       onLoad.error("Invalid package name: ",name); 
      } 
     } 
    } 
}); 

và sử dụng nó như vậy:

var world_module = "define([],function(){return 'world!'})"; 

require(["load-string!" + world_module], 
    function(x){ 
     console.log("Hello "+x); 
    })